1 / 51

Prolog

Prolog. Prolog Keeps us away from the machine Search algorithms are built into the language Clearly defined semantics since it’s based on FOPL Easily extendable—necessary since AI programming is exploratory Basic unit is the rule Scope of variables restricted to a single rule

junius
Download Presentation

Prolog

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

  2. Prolog • Keeps us away from the machine • Search algorithms are built into the language • Clearly defined semantics since it’s based on FOPL • Easily extendable—necessary since AI programming is exploratory • Basic unit is the rule • Scope of variables restricted to a single rule • Modifications are simplified Why AI Programming Languages?

  3. Describe the problem in terms of its logical constraints • That is, tell the computer what is true • Pattern search then looks for a solution Task in Prolog

  4. Grew out of work on theorem proving using resolution refutation • Invented in France in the early 70’s as part of work on NLP • Standard Prolog is called Clocksin and Mellish • Developed in the AI lab at the University of Edinburgh in late 70’s History

  5. No control structure • Not guaranteed to halt • CNF is difficult to work with EX: V X (~rain(X) ^ sunny(X)  blue_sky(X)) becomes in CNF rain(X) V ~sunny(X) V blue_sky(X) Problems with FOPL

  6. Horn Clauses joined with a depth-first search, backtracking regimen answers all objections • Def Horn Database A database is horn if it is equivalent to set of sentences of the form: a1 ^ … ^am  b Where b is a single positive predicate rain(X) ^ cold(X)  cloudy(X) Horn Clauses

  7. Most T/F knowledge we have about the world can be described in horn form John is a lawyer or a waiter ~lawyer(john)  waiter(john) • Horn DB have attractive computational properties • In a horn DB, the time needed to determine whether or not a particular item follows is O(N*D) • where N is the maximum number of premises in any rule and D is the number of rules in the database • Modus Ponens is capable of finding every valid consequence in a horn DB Properties of Horn Clauses

  8. a  b is written b:- a • a ^ b  c is written c :- a, b. • ~a ^ b  c is written c :- ~a, b. • Facts are entered like this: prof(paul) A Prolog program is a horn database with these modifications

  9. All prolog variables are assumed to be universally quantified Universal Quantifiers

  10. Case 1: The value the existentially quantified variable is known • likes(paul,simcha) is an instance of V X(likes(paul,X)) i.e., there exists X (likes(paul,X)) So likes(paul,simcha) may be entered directly Existential Quantifiers

  11. Case 2: Ask Prolog to find a value that makes the expression true -likes(paul, X) Prolog will determine whether a value of X exists under which the expression is true.

  12. Anything is false whose opposite is not provably true If you query the DB and your query cannot be proved true, then your query is assumed to be false. Suppose we have these predicates in the db: likes(paul,simcha) likes(paul,binky) If we ask likes(paul,skiing) Prolog responds “no” So, all knowledge for a particular universe of discourse is in the DB. If something is not in the DB, that something is false. Closed World Assumption

  13. To start prolog, type swipl (on ada) or prolog (on the VM • To get out: type halt: ?- halt. • To enter a db you’ve created in a file • Store the db with an extension pl (pgm1.pl) • type consult(pgm1): ?- consult(pgm1). or [pgm1] ?- [pgm1] • To see the current DB, type listing: ?- listing. • To trace execution, type trace: ?-trace. • To turn off tracing, type notrace: ?- notrace. Prolog Commands

  14. A list is an ordered collection of elements, consisting of: • Head – the first element in the list • Tail – everything else which is a, possibly empty, list • Syntax: [a|b,c,d] • Head = a • Tail = [b,c,d] • Elements in a list are enclosed w/in brackets: [b,c,d] • Head can be separated from tail with | [a|b,c,d] • _ in H or T position means we don’t care about it: [a|_] Lists

  15. An element is a member of a list if • It is the head of the list • It is a member of the tail • But an element is a member of the tail • If it is the head of the tail • If it is a member of the tail of the tail … Member Checking

  16. mem(A, [A|_). mem(A, [_|Tail) :- mem(A,Tail). More Precisely

  17. Mem(a,[c,b,a]) T Mem(a,[b,a]) R1--F T R1--F Mem(a,[a]) Trace T R1--T

  18. Display the head • Display the head of the tail • Display the head of the tail of the tail • … • Continue this process until the list is empty write(arg) : displays arg write(nl) : causes carriage return/new line Displaying a List

  19. writelist([]). writelist([H|T]) :- write(H), nl, writelist(T). More Precisely

  20. writelist([a,b,c]). R1-F R2 write(a) a write(nl) newline writelist([b,c]) R1-F R2 write(b) b write(nl) newline writelist([c]) R1-F R2 write(c) c write(nl) newline writelist([]) R1-T T T T Trace

  21. reverse(L,R) • Pop items from L • Push them onto an empty list • When L is empty all items will be on the buffer list in reverse order • Copy buffer list to R Reversing Elements in a List

  22. rev(L,R) :- rev1(L, [], R). rev1([], Temp, Temp). rev1([H|T], Temp, R) :- rev1(T,[H|Temp], R). More Precisely

  23. rev([a,b,c],R) rev1([a,b,c], [], R) R1-F rev1([b,c], [a|[]], R) R1-F rev1([c], [b|a], R) R1-F rev1([], [c|b,a], R) R1-T {[c,b,a]/R} T {[c,b,a]/R} T {[c,b,a]/R} T {[c,b,a]/R} T {[c,b,a]/R} T {[c,b,a]/R} Trace

  24. Reverse the List Then Write it out Writing Out a List in Reverse

  25. rev_write1(L) :- rev(L,R), writelist(R). More Precisely

  26. Requires two recursive calls Elegant, but there’s a problem

  27. Take advantage of the fact that reverse unwinds the list and gives access to the head at every level. At the bottom level is the last item in the list: rev(L,R) :- rev1(L, [], R). rev1([], Temp, Temp). rev1([H|T], Temp, R) :- rev1(T,[H|Temp], R). And the single clause, write(H), to the last premise Giving: rev_write2(L,R) :- work(L, [], R). work([], Temp, Temp). work([H|T], Temp, R) :- work(T,[H|Temp], R), write(H). Solutiion

  28. Leads to: rev_write3(L) :- work(L, []). work([], Temp, Temp). work([H|T], Temp) :- work(T,[H|Temp]), nl, write(H). What Else? But notice that we don’t use R

  29. This eliminates the need for a separate clause containing the empty list as an argument. rev_write4([]). rev_write4([H|T]) :- rev_write4(T), nl, write(H). We don’t need to push the head onto the stack.

  30. rev_write4([a,b,c]) R1-F rev_write4([b,c]) R1-F rev_write4([c]) R1-F rev_write4([]) R1-T nl write(c) T nl write(b) T nl write(a) T T Trace

  31. Technique • Pick up list 1 • Slide list 2 under it • Put list 1 down. Appended list is Result append(L1, L2, Result). Appending one list to another

  32. append([], L2, L2) If list 1 is empty, unification copies list 2 to Result Rule 1: Base Case

  33. app(H|T, L2, [H|R]) :- app(T, L2, R). If L1 (i.e., the first arg)has at least 1 item • Copy head of L1 to head of R on LHS • Pop head from L1 on RHS • Eventually, L1 will be empty. • Base case will succeed • R on the RHS holds L2 • As recursion unwinds, the elements of L1 appear at the front of L2 on the RHS in reverse order. Rule 2: Recursion

  34. app([], L, L). app(H|T, L2, [H|R]) :- app(T, L2, R). Append

  35. app([a,b], [c,d], R) {[a,b,c,d]/R} R1-F app([a,b],[c,d], [a|R] if app([b],[c,d],R) {[b,c,d]/R} R1-F app([b],[c,d],[b|R]) if app([],[c,d],R) R1-T {[c,d]/R} Trace

  36. Suppose N is a number and X is a variable Then “X is N + 1” causes X to be bound to the value of N + 1 Technique • Basis • Length of list with no elements is 0 • Len([],0) • Recursive step? Length of a List

  37. Length of a non-empty list is the length of its tail + 1 • Len([H|T],L) :- len(T, Lt), L is Lt + 1. Recursive step

  38. len([a,b,c],L) R1-F len([a|b,c], L) if len([b,c],Lt), L is Lt + 1 R1-F len(b,c],L) {2/Lt} if len([c], Lt), L is Lt + 1 {1/Lt} R1-F len([c],L) if len([],Lt), L is Lt + 1 {1/L} R1-T {0/Lt} Trace

  39. Stacks • Queues Two Data Structures

  40. A stack is empty if the list is the empty list • empty([]) Empty

  41. Argument 1 is the element to be pushed • Argument 2 is the stack • Argument 3 is the new stack • push(Top, Stack, [Top|Stack]) Push

  42. Same as push, but this time the second argument is the new stack • pop(Top, Stack, [Top|Stack]) Pop

  43. We can use our member program • isIn(Elt,Stack) :- mem(Elt,Stack) isIn

  44. Technique • Pop the stack until empty • Then write elements as recursion unwinds Write (Reverse)

  45. write_r(Stack) :- empty(Stack). write_r(Stack) :- pop(Top,Rest,Stack), write_r(Rest), write(Top), nl.

  46. A little harder since we have to traverse the underlying list either for enqueue Queue

  47. empty([]). • isIn(Elt,Stack) :- mem(Elt,Stack) • serve(Top, Stack, [Top|Stack]) Empty, isIn, and serve are identical to empty, isIn, and pop for stack

  48. Necessary to recursively traverse the list • If the queue is empty, the enqueued element is the queue • enqueue(Elt, [], [Elt]). • Else pick up the queue, item by item, slide in the new element and replace the queue • enqueue(Elt, [H|T], [H|Tnew]) :- enqueue(Elt, T, Tnew). Enqueue

  49. writeQ(Queue) :- empty(Queue). writeQ(Queue) :- serve(Top,Rest,Queue), write(Top), nl, writeQ(Rest). Writing the Queue is easy

  50. Basis: person A is the ancestor of person B, if person A is the parent of person B. • ancestor(A,B) :- parent(A,B). • Recursive Step: Person A is the ancestor of person C, if person A is the ancestor of person B and person B is the ancestor of person C • ancestor(A,C) :- parent(A,B), ancestor(B,C). Recursion without listsThe Ancestor Problem

More Related