1 / 45

Introduction to PROLOG ME- 409

Introduction to PROLOG ME- 409. Lab 2 Instructor: Prof. P.G.Awate. Controlling Backtracking. PROLOG programs have got two meanings: Declarative and Procedural. Both these meanings come from declaration of rules. Procedural meaning tells us how the program functions.

paloma
Download Presentation

Introduction to PROLOG ME- 409

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Introduction to PROLOGME- 409 Lab 2 Instructor: Prof. P.G.Awate

  2. Controlling Backtracking • PROLOG programs have got two meanings: Declarative and Procedural. Both these meanings come from declaration of rules. • Procedural meaning tells us how the program functions. • Declarative meaning is nothing but telling fact that it is about programming in logic and first order predicate calculus.

  3. CUTS • Its basically a control structure having significant procedural meaning and no declarative meaning. • Cuts are extra-logical predicate which are part of rule definition. • Cuts are used in PROLOG to prevent the unnecessary backtracking, but if used intelligently, they can also affect declarative meaning of the program.

  4. Types of Cuts • There are basically two types- • Green cuts- These are cuts which, when used in rules, affect procedural meaning of the program. They do NOT affect the declarative meaning • Red cuts- These are the cuts which affect both the procedural as well as declarative meaning of the program.

  5. Controlling backtracking :- example • Consider the double step function: • Rule 1: If X < 3, then Y = 0; • Rule 2: If 3 ≤ X < 6, then Y = 2; • Rule 3: If 6 ≤ X, then Y = 4. (figure 5.2) • Prolog code for the same can be written as: • f(X,0) :- X<3. • f(X,2) :- 3 =< X, X < 6. • f(X,4) :- 6 =< X. • Note: Function predicate is not intrinsic to Prolog

  6. Controlling backtracking :- example

  7. Controlling backtracking :- example • For the query: • ?- f(1,Y),2<Y. • In trying to satisfy this query, Prolog tries to satisfy it by checking all the three rules, although it is unnecessary. • In order to prevent unnecessary backtracking, cut ( ! ) statement can be introduced. • The code can be written as: • f(X,0) :- X<3, !. • f(X,2) :- 3 =< X, X < 6, !. • f(X,4) :- 6 =< X.

  8. Controlling backtracking :- example • In the above code, by using the cut, we tell PROLOG that these rules are exclusive. That is: • Y is 0 if and only if X < 3 • Y is 1 if and only if X < 6( and above fails) • Y is 2 if and only if 6 < X (and above fails) In the above code, even if cuts are removed, the answer doesn't change. So these are GREEN cuts.

  9. Controlling backtracking :- example • Using a cut may affect the results as well. The above program can be written more efficiently as: f(X,0):- X<3, !. f(X,2):- X<6, !. f(X,4). In this case we have intelligently used the cut to code the fact that if the first rule has failed then X is NOT less than 3 so the condition- 3 < X can be omitted from the second rule. But then if cuts are removed then the declarative meaning and thus output also changes. These are RED cuts.

  10. Controlling backtracking :- example • f(X,0):- X<3, !. f(X,2):- X<6, !. f(X,4). The declarative meaning of these rules are as: • Y is 0 if and only if X<3. • Y is 2 if and only if X<6. • Y is 4 not for all values of X. • The declarative meaning of these statements has changed.

  11. Negation • Facts and Rules are positive assertions about truth-hood of predicate. They are like confirmative tests to check that we are in P. Failure of this is taken as evidence that we are NOT in P. • So PROLOG programs themselves can never assert false-hood of predicates except in cases of logical contradictions. • The answer “FAIL” means that the program could not confirm the truthhoodness of the query from the given facts and rules. So there is no such thing as assertion of falsehood.

  12. Negation as failure • When failure to confirm the truth-hood of a predicate with given previous instantiations occurs, it is taken as negation for time being. • Its purely procedural meaning of the program. • The definition can be written as: • not (P):- P,!, fail ; true. Thus P is not true if the rules making P true fail.

  13. Eight Queens Problem (Without NOT) % query is ?-solution([1/Y1,2/Y2,3/Y3,4/Y4,5/Y5,6/Y6,7/Y7,8/Y8]). solution ( [] ). solution [ X/Y | Others ] ):- solution ( Others ), member ( Y, [1,2,3,4,5,6,7,8] ), noattack ( X/Y, Others ). noattack (_,[ ]). noattack (X/Y, [X1 / Y1| Others] ):- Y =\= Y1, Y1-Y =\= X1-X, Y1-Y =\= X-X1, noattack (X/Y, Others ). member ( Item, [Item |Rest ] ). member (Item,[ First |Rest] ):- member (Item, Rest).

  14. Here, solution is a predicate which holds position of queens in any order as the argument. Solution to null assignment is empty list: [ ]. Eight Queens Problem (Without NOT)

  15. Eight Queens Problem (With NOT) % query is ?-solution([1/Y1,2/Y2,3/Y3,4/Y4,5/Y5,6/Y6,7/Y7,8/Y8]). solution ( [] ). solution [ X/Y | Others ] ):- solution ( Others ), member ( Y, [1,2,3,4,5,6,7,8] ), not attacks ( X/Y, Others ). attacks (X/Y, Others ):- member ( X1/Y1, Others ), ( Y1 = Y; Y1 is Y + X1 - X; Y1 is Y - X1 + X ). member ( Item, [Item |Rest ] ). member (Item,[ First |Rest] ):- member (Item, Rest).

  16. Search Strategies • Depth first • To find a solution path, Sol, from a given node N, to some goal node: • If N is a goal node, then Sol = [N], or • If there is successor node, N1 of N, such that there is a path Sol1 from N1 to a goal node then Sol = [N|Sol1] • This translates into Prolog as • solve(N,[N]):-goal(N). • solve(N,[N|Sol1]):- s(N,N1),solve(N1,Sol1). • Note: s(X,Y) implies that Y is immediate successor of node X.

  17. Depth first • The program is called depth-first because of the order in which alternatives in the state space are explored. • For example: goal(e). directed_arc(c,e). directed_arc(c,d). directed_arc(d,c). directed_arc(b,c). directed_arc(a,b). solve(N,[N]):- goal(N). solve(N,[N|Sol1]):- directed_arc(N,N1), solve(N1,Sol1).

  18. Depth first • The query: • ? solve(a,Path). • Path = [a, b, c, e] ; • Path = [a, b, c, d, c, e] ; • Path = [a, b, c, d, c, d, c, e] • It can be seen in above example that the same node is visited repeatedly many times resulting into cycling.

  19. Depth first • The cycling of nodes in the path can be seen. The program can go into infinite loop in some cases if this is not prevented. For e.g.: goal(e). directed_arc(c,d). directed_arc(c,e). directed_arc(d,c). directed_arc(b,c). directed_arc(a,b).

  20. Depth first solve(N,[N]):- goal(N). solve(N,[N|Sol1]):- directed_arc(N,N1), solve(N1,Sol1). • For the query: • ?-solve(a,Path). ERROR: Out of local stack

  21. Depth first • Cycling can be avoided in depth-first search by preventing addition of already existing nodes in the path again. • The corresponding depth first search code can be written as (figure 11.7):

  22. Depth first with cycling of nodes in the path avoided: % solve ( Node, Solution): Solution is an acyclic path (in reverse order) between Node and a goal. solve (Node, Solution):- depthfirst ( [ ], Node, Solution). % depthfirst (Path, Node, Solution): Extending the path [Node | Path] to a goal gives solution. depthfirst (Path, Node, [Node | Path] ) :- goal (Node). depthfirst (Path, Node, Sol):- s(Node,Node1), not member(Node1,Path), % Prevents a cycle depthfirst ([Node| Path], Node1, Sol).

  23. Depth first with limited depth • To avoid aimless infinite (non-cyclic) branches, we can add another refinement to the basic depth-first search procedure limiting the depth of the search. • The code is given as follows: ( Figure 11.8, Bratco.

  24. % depthfirst2 ( Node, Solution, Maxdepth ): % Solution is a path, not longer than Maxdepth, % from Node to a goal. depthfirst2 ( Node, [ Node ], _ ) :- goal ( Node ). depthfirst2 ( Node, [ Node| Sol], Maxdepth ) :- Maxdepth > 0, s ( Node, Node1), Max1 is Maxdepth - 1, depthfirst2 ( Node1, Sol, Max1 ). Depth first with limited depth

  25. Breadth first • In contrast to depth-first strategy, breadth-first search strategy chooses to first visit those nodes that are closest to the start node. The algorithm can be given as follows: ( Fig. 11.10, Bratco)

  26. % solve( Start, Solution):- % Solution is a path in reverse order from start to goal. solve (Start, Solution) :- breadthfirst( [ [Start] ], Solution ). % breadthfirst ( [ Path1,Path2,...], Solution) : % Solution is an extension to a goal of one of the paths breadthfirst ( [ [ Node| Path ] | _], [Node| Path ] ) :- goal ( Node). Breadth first

  27. Breadth first breadthfirst ( [ Path| Paths ], Solution ) :- extend ( Path, NewPaths ), conc( Paths, NewPaths, Paths1), breadthfirst ( Paths1, Solution ). extend ( [ Node| Path ], NewPaths ):- bagof ( [ NewNode, Node | Path ], ( s( Node, NewNode ), not member(NewNode, [Node | Path ] ) ), NewPaths ) !. extend ( Path [ ] ). % bagof failed : Node has no successor.

  28. Train marshalling problem • An engine attached to the right hand side end of a rake (a sequence of serially connected wagons) has bought the rake and parked it on track ‘A’ , to the left of adjustable crossing C1. Let this rake be denoted as list R1=[n1,n2,..nk] where ni is the distinctive wagon number of the ith wagon from the left hand side end of the rake (having k wagons). The engine driver is required to assemble rakes R2 and R3 on tracks B and C respectively, which are similarly lists of wagon numbers starting from the LHS end.

  29. Train marshalling problem R2=[np1,np2…npa] and R3=[npa+1,npa+2,…npk] where (p1,p2,…pk) is an arbitrary specified permutation of (1,2…k). At any time in general if R1’, R2’, R3’ are intermediate rakes present on tracks A,B,C respectively, the engine driver can split any rake Ri’ into exactly 2 parts say R’i,l ( the LHS part of the list- called prefix) and R’i,r ( the remaining complimentary part- called suffix) Then the driver can take suffix R’i,r by itself to track D and by backing up, attach it as a suffix to an existing rake R’j to create an new rake R’’j whose prefix is R’j and suffix is R’i,r.

  30. Train marshalling problem • The objective is to assemble R2 in track B and R3 in track C out of R1 in track A. (Given the specifications of R1,R2,R3) • This problem can be solved using breadth first search in the space of plans( sequence of transfers), in increasing order of the number of transfers in the plan.

  31. Train marshalling problem • Solution using breadth first search: solve(R1,R2,R3,Solution):- consistent(R1,R2,R3), %R1, R2, R3 are consistent L1=R1, % wagons in track 1 L2=[], % wagons in track 2 L3=[], % wagons in track 3 Initialstate=[L1,L2,L3,[]], % list of wagons in three tracks and % transfers done Finalstate=[[],R2,R3,_], bfs([Initialstate],Finalstate, Solution). • State here is a list of wagons in all the three tracks and the transfers made to achieve that arrangement

  32. Train marshalling problem • bfs(List_of_states, Finalstate, Solution) bfs([Head|Tail],Finalstate, Solution):- Head=Finalstate, Finalstate=[L1,L2,L3,Transfers], Solution = Transfers. % if first three elements of the Finalstate list are matched with those of Head, the last element in the Finalstate list is matched with last element of Head. % Transfers is then matched with the last element of the of Finalstate and Solution is matched with Transfers. bfs([Head|Tail],Finalstate, Solution):- extend(Head,Headneighbours), conc(Tail, Headneighbours,L), bfs(L, Finalstate, Solution).

  33. Train marshalling problem extend(Head, Headneighbours):- bagof( Node, (arc(Head,Node)), Headneighbours). %Track 1 -> Track 2 arc(A,B):- A=[L1A, L2A, L3A, TransfersA], % current list of wagons and transfer % till now conc(Pre,Post,L1A), % new list of wagons in track 1 not(Post=[]), conc(L2A, Post, L2B), % new list of wagons in track 2 conc(TransfersA, [transfer(Post, t1, t2)], TransfersB), % updating the % transfers B=[Pre,L2B,L3A,TransfersB]. • The arc rule is written for all possible combinations ( 1->3, 2->1, 2->3, 3->1, 3->2) of transfers.

  34. Train marshalling problem permutation([],[]). permutation([X|L],P):-permutation(L,L1),insert(X,L1,P). consistent(R1,R2,R3):-conc(R2,R3,RR), permutation(R1,RR). • The efficiency of the code can be improved by inclusion of regularity conditions (that isif any two wagons are adjacent in R2 or R3), and occur in the same order and are adjacent in R1 also, then the plan should never de-link these two wagons in any of the transfers)

  35. Train marshalling problem • Regularity condition can be built in while extending the node. bfs([Head|Tail],Finalstate, Solution):- Head=Finalstate, Finalstate=[L1,L2,L3,Transfers], Solution = Transfers. bfs([Head|Tail],[ _, R2, R3,_ ], Solution):- extend(Head,Headneighbours, R2,R3), conc(Tail, Headneighbours,L), bfs(L, [ _ ,R2, R3, _ ], Solution).

  36. Train marshalling problem extend(Head, Headneighbours, R2,R3):- bagof( Node, (arc(Head,Node,R2,R3)), Headneighbours). %Track 1 -> Track 2 arc(A,B):- A=[L1A, L2A, L3A, TransfersA], conc(Pre,Post,L1A), % new list of wagons in track 1 not(Post=[]), not(member(transfer(Post,t1,t2),TransfersA)), check_regularity(Post,L1A,R2,R3), conc(L2A, Post, L2B), % new list of wagons in track 2 conc(TransfersA, [transfer(Post, t1, t2)], TransfersB), B=[Pre,L2B,L3A,TransfersB].

  37. Train marshalling problem %check_regularity(L,L1,R2,R3) checks that regularity condition (wagons adjacent in R2 or R3 ) are never delinked) is satisfied in moving suffix L of L1 % regularity condition is satisfied in moving complete list. check_regularity(CR1,CR1,_,_). %regularity condition is satisfied if the first element of the suffix of List and the last element of prefix does not occur as a sublist in either R2 or R3 check_regularity([X|L],List,R2,R3):- conc(Prefix,[X|L],List), last(Y,Prefix), not(sublist([Y|[X]],R2)), not(sublist([Y|[X]],R3)).

  38. Train marshalling problem %last(Y,L) : Y is the last element of list L last(Y,Prefix):- member(Y,Prefix), conc(_,[Y],Prefix), !. %L is the sublist of L1 sublist(L,L1):- conc(_,L3,L1), conc(L,_,L3). • the breadth-first strategy in general becomes very expensive, both in CPU time as well as memory. • Fairly-good heuristics can generate solutions relatively more inexpensively.

  39. Train marshalling problem • Here we use the following heuristic technique as the strategy for generating the solution: • Driver finds a maximal prefix (sublist of a list with same head as that o the list) of R2 that appears as a sublist L1 in R1. • Then he parks the suffix to the right of L1 in R1 in track C, transfers L1 to track B and brings back suffix parked in track C and makes it the suffix of the modified rake in track A. • Likewise he assembles the entire rake R2, segment (sublist) by segment, each time using track C for parking suffixes only.

  40. Train marshalling problem • AFTER fully assembling rake R2, (at which time track C is made empty also ) the driver the assembles rake R3 in track C, using track B as shunting space only( to the right of already assembled rake R2 already in track B).

  41. Train marshalling problem move(R1,R2,R3,FinalPlan):- plan(R1,[],[],[],R2,R3,FinalPlan). % plan(CurrentR1,CurrentR2,CurrentR3,CurrentPlan,R2,R3,FinalPlan) %The current lists of wagons on track a,b,c are given by CurrentR1,CurrentR2,CurrentR3 respectively. % The CurrentPlan is the list of transfers that needs to be done to reach from initial state to current state. %if CurrentR2 and CurrentR3 are same as R2 and R3 then CurrentPlan is same as FinalPlan plan([],R2,R3,FinalPlan,R2,R3,FinalPlan).

  42. Train marshalling problem % when wagons in track b have been arranged properly: plan(CurrentR1,R2,CurrentR3, CurrentPlan, R2, R3, FinalPlan):- conc(CurrentR3,RestR3,R3), maximal_prefix(RestR3, CurrentR1, [],R), % R is the maximal % prefix of RestR3 that occurs as a sublist in CurrentR1. conc(_,L2,CurrentR1), conc(R,L3,L2), % L3 is the list of wagons to the right of R shunting1(R,L3,Actions), % Actions are the list of actions % (transfer(R, Track1, Track2)) to be performed while shunting conc(CurrentPlan,Actions,CPlan1), remove(CurrentR1,R,NewR1), % removing sublist R from % CurrentR1 to get NewR1 conc(CurrentR3,R,NewR3), % adding R to the right of % CurrentR3 to get NewR3 plan(NewR1,R2,NewR3,CPlan1,R2,R3,FinalPlan).

  43. Train marshalling problem plan(CurrentR1,CurrentR2,[], CurrentPlan,R2,R3,FinalPlan):- conc(CurrentR2,RestR2,R2), maximal_prefix(RestR2, CurrentR1, [],R), conc(_,L2,CurrentR1), conc(R,L3,L2), shunting2(R,L3,Actions), conc(CurrentPlan,Actions,CPlan1), remove(CurrentR1,R,NewR1), conc(CurrentR2,R,NewR2), plan(NewR1,NewR2,[],CPlan1,R2,R3,FinalPlan). shunting1(R,[],[transfer(R,a,c)]). % When there is no wagons to the right hand side of R shunting1(R,L3,[transfer(L3,a,b),transfer(R,a,c),transfer(L3,b,a)]). %when CurrentR2 is not same as R2 the procedure is same using track 3 for shunting

  44. Train marshalling problem shunting2(R,[],[transfer(R,a,b)]). shunting2(R,L3,[transfer(L3,a,c),transfer(R,a,b),transfer(L3,c,a)]). %maximal_prefix(List1,List2,CurrentList,MaximalList) % MaximalList is the maximum prefix list of List1 that appears as a sublist of List2, and is generated by extending CurrentLis maximal_prefix([X|R2],R1,CurrentR,R):- conc(CurrentR,[X],CurrentR1), sublist(CurrentR1,R1), !, maximal_prefix(R2,R1,CurrentR1,R). maximal_prefix([],_,CurrentR,CurrentR). maximal_prefix(_,_,CurrentR,CurrentR).

  45. Train marshalling problem %L is the sublist of L1 sublist(L,L1):- conc(_,L3,L1), conc(L,_,L3). conc([],X,X). conc([X|L1],L2,[X|L]):- conc(L1,L2,L). %removes sublist R from list R1 to get new list NR1 remove(R1,R,NR1):- conc(L1,L2,R1), conc(R,L3,L2), conc(L1,L3,NR1).

More Related