1 / 44

Prolog for Linguists Symbolic Systems 139P/239P

Prolog for Linguists Symbolic Systems 139P/239P. John Dowding Week 3, October 22, 2001 jdowding@stanford.edu. Course web page. http://www.stanford.edu/class/symbsys139p programs used in class power point slides homework assignments, solutions

Download Presentation

Prolog for Linguists Symbolic Systems 139P/239P

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 for Linguists Symbolic Systems 139P/239P John Dowding Week 3, October 22, 2001 jdowding@stanford.edu

  2. Course web page • http://www.stanford.edu/class/symbsys139p • programs used in class • power point slides • homework assignments, solutions • This gets updated by Tuesday night after Monday’s class.

  3. Office Hours • We have reserved 4 workstations in the Unix Cluster in Meyer library, fables 1-4 • Skipping 4:30-5:30 on Thursday this week • Friday 3:30-4:30, after NLP Reading Group this week • If not, contact me and we can make other arrangements

  4. Course Schedule • Oct. 8 • Oct. 15 • Oct. 22 • Oct. 29 (double up) • Nov. 5 • Nov. 12 • Nov. 26 (double up) • Dec. 3 No class on Nov. 19

  5. Prolog Execution Model/Prolog Debugger EXIT CALL FAIL REDO

  6. Linked Lists • Prolog allows a special syntax for lists: • [a,b,c] is a list of 3 elements • [] is a special atom indicating a list with 0 elements • Internally, Prolog lists are regular Prolog terms with the functor ‘.’ (so called “dotted pairs”) • [a,b,c] = ‘.’(a, ‘.’(b, ‘.’(c, []))). • The symbol | in a list indicates “rest of list”, or the term that is the 2nd argument of a dotted pair. • [a,b,c] = [a|[bc]]. • [Head|Tail] is a common expression for dividing a list into its first element (Head) and the rest of the list (Tail).

  7. Homework • Read section in Sicstus Prolog manual on debugger. • Use debugger to trace through today’s example programs and understand how the work. • Implement: • delete_all(+Element, +List, -NewList) that removes all occurrences of Element from List to find NewList. • replace_all(+Element, +List, +NewElement, -NewList) replaces every occurrence of Element with NewElement in List to give NewList.

  8. Homework: delete_all/3 %delete_all(+Element, +List, -NewList) delete_all(_Element, [], []). delete_all(Element, [Element|List], NewList) :- !, delete_all(Element, List, NewList). delete_all(Element, [Head|List], [Head|NewList]) :- delete_all(Element, List, NewList).

  9. Homework: replace_all/4 %replace_all(+Element, +List, +NewElement, -NewList) replace_all(_Element, [], _NewElement, []). replace_all(Element, [Element|List], NewElement, [NewElement|NewList]) :- !, replace_all(Element, List, NewElement, NewList). replace_all(Element, [Head|List], NewElement, [Head|NewList]) :- replace_all(Element, List, NewElement, NewList).

  10. “Pure Prolog” and non-logical built-ins • All the examples so far have been “pure Prolog” • Contain no built-ins with non-logical side-effects • Prolog has many built-in predicates that have such side-effects: • Type checking of terms • Arithmetic • Control execution • Input and output • Modify the program during execution • Perform aggregation operations • Use of non-logical built-in predicates usually effects the reversability of your program.

  11. Type-checking Built-in Predicates • var(X) – is true when X is an uninstantiated variable. • nonvar(X) – is true when X is not a variable. • atom(X) – is true when X is a symbolic constant. • number(X) – is true when X is a number • atomic(X) – is true when atom(X) or number(X). • compound(X) – is true when X is a compound term.

  12. Term constructor/selectors: functor/3, arg/3 functor(+Term, ?Functor, ?Arity) • Find the Functor and Arity of Term functor(?Term, +Functor, +Arity) • Constructs a new Term with Functor and Arity arg(+N, +Term, ?SubTerm) • Unifies SubTerm with the Nth argument of Term

  13. Arithmetic: Built-In is/2 • Arithmetic expressions are not normally evaluated in Prolog. • Built-In infix operatoris/2 evaluates it’s 2nd argument, and unifies the result with it’s 1st argument. | ?- X = 5 + 2. X = 5+2? yes | ?- X is 5 + 2. X = 7 ? yes • Any variables in the right-hand side of is/2 must be instantiated when it is evaluated. • Revisit operator and arithmetic at a later time

  14. Cut (!) • The ! Symbol (pronounced “cut”) modifies the execution of your program by committing to certain choices. • That is, it removes choice points. • Removes any choice points that have been created since the predicate was invoked. • Easy to describe what it does, more difficult to get used to using it properly.

  15. Cut (cont.) Head1 :- Goal1, Goal2, …, GoalN, !, … Head2 :- … Head3 :- … … HeadN :- … • Removes the choice point that allows Head2 …HeadN • Removes any choice points that may have been introduced in Goal1 … GoalN. • We will discuss Cut in more detail later on.

  16. Example: is_term/1 is_term(Atomic) :- atomic(Atomic). is_term(Variable):- var(Variable). is_term(CompoundTerm):- compound(CompoundTerm), functor(CompoundTerm, _Functor, Arity). is_term_helper(Arity, CompoundTerm). is_term_helper(0, _CompoundTerm) :- ! is_term_helper(Index, CompoundTerm):- arg(Index, CompoundTerm, SubTerm), is_term(SubTerm), NextIndex is Index – 1, is_term_helper(NextIndex, CompoundTerm).

  17. Built-Ins: Term Comparison Operators • Unifies with • Term1 = Term2 iff unifies Term1 and Term2 if they are unifiable • Does not unify with • Term1 \= Term2, Term1 and Term2 are unchanged • Identical • Term1 == Term2 iff are the same terms • Not identical • Term1 \== Term2

  18. Example: unify/2 (without occurs check) unify(Var1, Term2):- var(Var1), !, Var1 = Term2. unify(Term1, Var2):- var(Var2), !, Var2 = Term1. unify(Atomic1,Atomic2):- atomic(Atomic1), atomic(Atomic2), !, Atomic1 == Atomic2. unify(Term1, Term2):- compound(Term1), compound(Term2), functor(Term1, Functor, Arity), functor(Term2, Functor, Arity), unify_helper(Arity, Term1, Term2).

  19. Example: unifiable/2 (continued) unify_helper(0, _Term1, _Term2):- !. unify_helper(Index, Term1, Term2):- arg(Index, Term1, Arg1), arg(Index, Term2, Arg2), unify(Arg1, Arg2), NextIndex is Index – 1, unify_helper(NextIndex, Term1, Term2).

  20. Example: identical/2 identical(Var1, Var2):- var(Var1), var(Var2), !, Var1 == Var2. identical(Atomic1,Atomic2):- atomic(Atomic1), atomic(Atomic2), !, Atomic == Atomic2. identical(Term1, Term2):- compound(Term1), compound(Term2), functor(Term1, Functor, Arity), functor(Term2, Functor, Arity), identical_helper(Arity, Term1, Term2).

  21. Example: identical/2 (continued) identical_helper(0, _Term1, _Term2):- !. identical_helper(Index, Term1, Term2):- arg(Index, Term1, Arg1), arg(Index, Term2, Arg2), identical(Arg1, Arg2), NextIndex is Index – 1, identical_helper(NextIndex, Term1, Term2).

  22. Unification • Two terms unify iff there is a set of substitutions of variables with terms that makes the terms identical • True unification disallows cyclic terms: • X=f(X) ought to fail because there is no finite term that can substitute for X to make those terms identical. • This is called the occurs check. • Prolog unification does not enforce the occurs check, and may create cyclic terms • Occurs check is expensive • O(n) – n is the size of the smaller of the two terms • O(n+m) – n and m are the sizes of the two terms • In Prolog, it is quite typical to unify a variable with a larger term

  23. Built-ins: true/0 and fail/0. • true. • Always succeeds. • fail. • Always fails.

  24. Meta-Predicates: call/1, \+/1 • Meta-predicates take a Goal as an argument, and execute it. • call/1 executes it’s one argument. • \+(Goal) succeeds if call(Goal) fails. • \+/1 could also be defined using cut and fail. \+(Goal) :- call(Goal), !, fail. \+(_Goal).

  25. Example: select/3 % select(+List, +Condition, -Element) select(List, Condition, Element):- member(Element, List), call(Condition). • This might be called with something like: • select([a, 5, c, 7], integer(Element), Element) • select([1,2,3,4,5,6,7], Element < 5, Element). • select([1,2,3,4,5,6,7], (0 is Element mod 2), Element)

  26. More on non-logical predicates • \+ Goalis true if Goal fails. • \=, \==, and \+ introduce negation-as-failure • Not true negation, but failure-to-prove • A little bit of ‘non logical’ takes you a long way

  27. Another way to write delete_all/3 delete_all(_Element, [], []). delete_all(Element, [Element|List], NewList) :- delete_all(Element, List, NewList). delete_all(Element, [Head|List], [Head|NewList]) :- Element \== Head, delete_all(Element, List, NewList).

  28. Accumulators • Build up partial results to return at the end list_length([], 0). list_length([_Head|Tail], Result):- list_length(Tail, N), Result is N +1. list_length(List, Result) :- list_length_helper(List, 0, Result). list_length_helper([], Result, Result). list_length_helper([_Head|Tail], Partial, Result):- NextPartial is Partial + 1, list_length_helper(Tail, NextPartial, Result).

  29. Acccumulators: efficient reverse/3 % reverse(+List, -ReversedList) reverse(List, ReversedList):- reverse_helper(List, [], ReversedList). reverse_helper([], ReversedList, ReversedList). reverse_helper([Head|Tail], PartialList, ReversedList):- reverse_helper(Tail, [Head|PartialList], ReversedList).

  30. Difference Lists • Use two logical variables that point to different portions of the same list. • Compare stacks with queues:

  31. Stacks % empty_stack(?Stack) – true if Stack is empty empty_stack([]) % push(+Item, +Stack, -NewStack) push(Item, Stack, [Item|Stack]). %pop(+Stack, -Item, -NewStack) pop([Item|NewStack], Item, Stack).

  32. Queues • Queue represented as a pair of lists (Front-Back) • Back is always a variable %empty_queue(?Queue) – true if the queue is empty empty_queue(Queue-Queue). %add_to_queue(+Element, +Queue, -NewQueue) add_to_queue(Element, (Front-[Element| Back]), (Front-Back)). %remove_from_queue(+Queue, -Element, -NewQueue) remove_from_queue(([Element|Front]-Back), Element, (Front-Back)).

  33. Appending Difference Lists • Appending difference lists is very efficient append_dl((Front-Next), (Next-Back), (Front-Back)). • These uses of difference lists are incomplete data structures • Differenced lists are also useful as complete data structures • Considering using difference lists is situations where you might otherwise be doing a lot of appends.

  34. Generate-and-Test • Popular (and sometimes efficient) way to write a program. Goal :- Generator, - generates candidate solutions Tester. - verifies correct answers

  35. Example: select/3 % select(+List, +Condition, -Element) select(List, Condition, Element):- member(Element, List), - generates potential solutions call(Condition). - verifies that the meet the condition

  36. Example: slow_sort/2 % slow_sort(+List, -SortedList) slow_sort(List, PermutedList):- permute(List, PermutedList), is_sorted(PermutedList). %permute(+List, -Permutation) permute([], []). permute([Head|Tail], Permutation):- permute(Tail, PermutedTail), insert(Head, PermutedTail, Permutation).

  37. Example: slow_sort/2 (cont.) % insert(+Element, +List, -BiggerList) insert(Element, List, [Element|List]). insert(Element, [Head|List], [Head|BiggerList]):- insert(Element, List, BiggerList). % is_sorted(+List) is_sorted([]). is_sorted([_OneElement]). is_sorted([FirstElement, SecondElement|Tail]):- FirstElement =< SecondElement, is_sorted([SecondElement|Tail]).

  38. Example: NPR Puzzle • Sunday morning’s weekly puzzle on KQED this week • Using a grid with 4 columns and 3 rows, find 3 four-letter words (along the rows) and 4 three-letter words (along the columns) that • Are all common words of English • Use each letter only once • Include all 6 vowels (a, e, i, o, u, y) • Assume two predicates: • three_letter_word(+First, +Second, +Third). • four_letter_word(+First, +Second, +Third, +Fourth).

  39. NPR Puzzle (cont) npr_puzzle:- choose_four_letter_words([A,B,C,D, E,F,G,H, I,J,K,L]), test([A,B,C,D, E,F,G,H, I,J,K,L]). write(A),write(B),write(C),write(D),nl, write(E),write(F),write(G),write(H),nl, write(I),write(J),write(K),write(L),nl, nl, fail.

  40. NPR Puzzle (cont) choose_four_letter_words([A,B,C,D, E,F,G,H, I,J,K,L]):- four_letter_word(A,B,C,D), four_letter_word(E,F,G,H), unique_letters([E,F,G,H], [A,B,C,D]), four_letter_word(I,J,K,L), unique_letters([I,J,K,L], [A,B,C,D,E,F,G,H]). unique_letters([], _). unique_letters([A|Rest], Letters):- \+ member(A, Letters), unique_letters(Rest,Letters).

  41. NPR Puzzle (cont) test([A,B,C,D, E,F,G,H, I,J,K,L]):- three_letter_word(A,E,I), three_letter_word(B,F,J), three_letter_word(C,G,K), three_letter_word(D,H,L), uses_all_vowels([A,B,C,D, E,F,G,H, I,J,K,L]),

  42. NPR Puzzle (cont) uses_all_vowels(Letters):- member(a, Letters), member(e, Letters), member(i, Letters), member(o, Letters), member(u, Letters), member(y, Letters).

  43. NPR Puzzle Results • After some futzing to get good lists of 3 and 4 letter words, and about 4 CPU hours, we get one solution: peas omit duly

  44. Homework • By now, we have covered most of Chapters 3 and 4 of Clocksin and Mellish. Read them and let me know if you have any questions. • Homework to be handed in by noon on the 29th.

More Related