1 / 23

Prolog OR (disjunction)

Prolog OR (disjunction). “;” is same as a logical OR It is also equivalent to using separate clauses... parent(X, Y) :- mother(X, Y). parent(X, Y) :- father(X, Y). SAME AS... parent(X, Y) :- mother(X, Y) ; father(X, Y).

Download Presentation

Prolog OR (disjunction)

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. Prolog OR (disjunction) COSC 2P93 Prolog: Cut “;” is same as a logical OR It is also equivalent to using separate clauses... parent(X, Y) :- mother(X, Y). parent(X, Y) :- father(X, Y). SAME AS... parent(X, Y) :- mother(X, Y) ; father(X, Y). Although this saves writing some code, both versions are equivalent in efficiency.

  2. Be careful with “;”! COSC 2P93 Prolog: Cut What is going on here? p(X) :- (q(X, Y) ; (r(Y), (s(U, Y); a(U), b(U)) ; r(X)), t(X, Y); w(X) ; z(A),z(B), etc... Too many or’s can make programs very hard to debug (trace)! Rule of thumb: Don’t use or’s in order to reduce number of clauses.

  3. Controlling Prolog execution COSC 2P93 Prolog: Cut • Prolog exhaustively searches the computation tree for solutions • If a goal fails, OR the user inputs ‘;’ at the prompt, then backtracking reverts to the last place in which a clause was chosen, and tries the next. • There are lots of advantages of this scheme, most notably, searching for a solution, or multiple solutions, to a query. • However, it can be expensive: • Sometimes there is only one solution, and it is a waste of time searching for others -- they don’t exist! • Sometimes ‘failure’ after the first solution can take lots of time to infer • Memory resources are used to contain the computation tree for backtracking. • Prolog permits some user control of execution, in order to reduce backtracking.

  4. 1. If-then-else COSC 2P93 Prolog: Cut (If -> Then ; Else) • If goals in If are true, then do Then; else do Else • Once Then is executed, will go to Then or Else, but cannot backtrack from Then to Else, nor back to If. • Backtracking will return multiple solutions in Then, and in Else. (If -> Then) • This is equivalent to: (If -> Then ; fail)

  5. Example If-then-else COSC 2P93 Prolog: Cut If N is prime, return ‘prime’, Else ‘notprime’. idNum(N, prime) :- prime(N). idNum(N, notprime) :- \+ prime(N). Note that prime/N is called twice – with identical results! Prime testing might be very slow for large integers, so this is very wasteful.

  6. Example if-then-else COSC 2P93 Prolog: Cut filterNum(N, Ans) :- (prime(N) -> Ans = prime ; Ans = notprime). Here, prime/1 is called once. No backtracking into it.

  7. 2. once COSC 2P93 Prolog: Cut • Often, we want just one solution from a predicate. • Multiple answers may slow execution, due to needless backtracking. once(Goal): • This calls Goal, and returns first solution. • Backtracking will immediately fail. • Built-in to Sicstus Prolog.

  8. Example of once/1 COSC 2P93 Prolog: Cut % delete(A, L, R): Delete A from L, resulting in R. delete(A, [A|T], T). delete(A, [B|T], [B|T2]) :- delete(A, T, T2). delete(_, [ ], [ ]). ?- delete(a, [a,b,a,c,a],L). L = [b,a,c,a] ? ; L = [a,b,c,a] ? ; L = [a,b,a,c] ? ; L = [a,b,a,c,a] ? ; ?- once( delete(a, [a,b,a,c,a],L) ). L = [b,a,c,a] ? ; no

  9. 3. The cut, ! COSC 2P93 Prolog: Cut • The cut takes the form of a goal in a clause. • Should use only one cut per clause. • A predicate can have one or more clauses with cuts. Scheme: 1. all the clauses before the first clause with a cut are executed with normal backtracking. 2. if the goals before the cut fail, the cut does not activate, and the subsequent clause is used, as normal. 3. if the goals before the cut succeed, the cut activates: a) backtracking back to goals before the cut cannot occur b) backtracking to subsequent clauses after the one with the cut cannot occur --> that clause with the activated cut is “committed” c) the goals after the cut are executed with normal backtracking

  10. The cut - example COSC 2P93 Prolog: Cut p(1). %1 p(2). %2 p(Y) :- q(3, Z), !, r(Z, Y). %3 p(4). %4 q(2, 4). r(5, 6). q(3, 5). r(5, 7). • Clauses 1, 2 are executed as normal • In 3, the goal q(3,Z) executes; if it succeeds, then the ! is activated, and the goal r is executed as normal. • However, in activating this cut... • clause 4 will not execute for this particular execution call • clause 3 will not backtrack to q again (in this goal inference) • Note that backtracking in r(Z,Y) occurs as expected, and hence you can still get multiple solutions from clause 3

  11. Green and red cuts COSC 2P93 Prolog: Cut • There are two usages of cuts: (i) Green cuts (GOOD): cuts that prune execution branches that do not lead to useful solutions. (ii) Red cuts (BAD): cuts that prune valid solutions

  12. Example: green cut COSC 2P93 Prolog: Cut % A list is bad if: (1) it is empty; (2) it has more than 100 items; or (3) it has an integer. test_list(L) :- test_if_bad(L), !, write(‘Bad list,’), nl, fail. % print message and fail test_list(L) :- write(‘Good list’), nl. % print message and succeed test_if_bad([ ]). test_if_bad(L) :- length(L, N), N > 100. test_if_bad(L) :- member(X, L), integer(X). • a “green cut”, because we know that only one of test_list clauses must succeed to say a list is bad. • backtracking makes no sense with it.

  13. Green cut COSC 2P93 Prolog: Cut • Note that we could do the same with if-then-else... test_list(L) :- (test_if_bad(L) -> write(‘Bad list,’), nl, fail ; write(‘Good list’), nl ).

  14. Example: red cut COSC 2P93 Prolog: Cut • A bad use of cut... parent(P, C) :- father(P, C), !. parent(P, C) :- mother(P, C). father(bob, sue). father(bob, kim). mother(mary, sue). mother(mary, kim). • A red cut: we get the first solution from father, and never give another valid solution again, from either father or mother! ?- parent(A, B). A = bob, B = sue ; no.

  15. Red cut COSC 2P93 : Cut • Variation: parent(P, C) :- !, father(P, C). parent(P, C) :- mother(P, C). (rest as before) ?- parent(A, B). A = bob, B = sue ; A = bob, B = kim ; no • Same as... parent(P, C) :- father(P, C).

  16. Implementation: If-then-else COSC 2P93 Prolog: Cut • If-then-else is implemented with a cut: P :- (If -> Then ; Else). Same as... P :- If, !, Then. P :- Else.

  17. Implementation: once/1 COSC 2P93 Prolog: Cut once(P) :- call(P), ! or... once(P) :- P, !. This is a “meta-logical” call. Usually built into Prolog.

  18. More cut examples COSC 2P93 Prolog: Cut • Example: a deterministic member/2: memberd/2 • deterministic clause: one that returns one solution per call member(A, [A|_). member(A, [_|R]) :- member(A, R). memberd(A, [A|_]) :- !. memberd(A, [_ | R]) :- memberd(A, R). • Here, as soon as memberd clause 1 finds a match, it succeeds • Subsequent backtracking to memberd then fails, due to the cut • we prevent memberd clause 2 from finding another match • Note: memberd same as... ?- once(member(X,Y)).

  19. Cut examples COSC 2P93 Prolog: Cut • Example: sum the integers between 1 and n sum_to(1, 1) :- !. sum_to(N, Sum) :- M is N - 1, sum_to(M, Tmp), Sum is Tmp + N. • Without the cut, backtracking proceeds to sum_to(0,_), sum_to(-1,...) etc • with the cut, when the case sum_to(1,1) occurs, backtracking will not commence (via clause 2) • again, a green cut: only one solution desired • BUT... simply checking size of N in 2nd clause will prevent need for a cut...

  20. Take out the cut... COSC 2P93 Prolog: Cut sum_to(1, 1). sum_to(N, Sum) :- N > 1, M is N - 1, sum_to(M, Tmp), Sum is Tmp + N.

  21. Cuts COSC 2P93 Prolog: Cut • Cuts are extralogical: they almost always destroy a program’s logical “declarative” reading. Consider test_list example again... test_list(L) :- test_if_bad(L), !, write(‘Bad list,’), nl, fail. test_list(L) :- write(‘Good list’), nl. • Read literally, the second clause says that all lists are good lists! • Hence we must now ascertain the meaning of this predicate by inspecting what the cut is doing. • The second clause’s meaning is dependent upon the first clause.

  22. Cuts COSC 2P93 Prolog: Cut • Cuts are unavoidable in many programs. Without them, the program can become too large and inefficient • However, cuts usually ruin a logic program’s readability • Careless use of cuts can make a Prolog program unintelligible, and hard to debug.

  23. When to use cuts COSC 2P93 Prolog: Cut • Try to make a declarative predicate if feasible: correct, concise, efficient. • Else, use “->” (if-then-else) or once/1 if they help. • Else, use a cut if it is a green cut. • Red cut: use as rarely as possible. Document their function!

More Related