prolog for linguists symbolic systems 139p/239p john dowding week 3, october 22, 2001
Post on 06-Jan-2018
216 Views
Preview:
DESCRIPTION
TRANSCRIPT
Prolog for LinguistsSymbolic Systems 139P/239P
John DowdingWeek 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
This gets updated by Tuesday night after Monday’s class.
Office Hours
We have reserved 4 workstations in the Unix Cluster in Meyer library, fables 1-4Skipping 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
Course Schedule
1. Oct. 82. Oct. 153. Oct. 224. Oct. 29 (double up)5. Nov. 56. Nov. 127. Nov. 26 (double up)8. Dec. 3
No class on Nov. 19
Prolog Execution Model/Prolog Debugger
CALL EXIT
FAIL REDO
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).
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.
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).
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).
“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.
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 numberatomic(X) – is true when atom(X) or number(X).compound(X) – is true when X is a compound term.
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
Arithmetic: Built-In is/2
Arithmetic expressions are not normally evaluated in Prolog.Built-In infix operator is/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
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.
Cut (cont.)
Head1 :- Goal1, Goal2, …, GoalN, !, …Head2 :- …Head3 :- ……HeadN :- …
Removes the choice point that allows Head2 …HeadNRemoves any choice points that may have been introduced in Goal1 … GoalN.We will discuss Cut in more detail later on.
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).
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
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).
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).
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).
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).
Unification
Two terms unify iff there is a set of substitutions of variables with terms that makes the terms identicalTrue 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 termsOccurs 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
Built-ins: true/0 and fail/0.
true. Always succeeds.
fail. Always fails.
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).
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)
More on non-logical predicates
\+ Goal is 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
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).
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).
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).
Difference Lists
Use two logical variables that point to different portions of the same list.
Compare stacks with queues:
Stacks
% empty_stack(?Stack) – true if Stack is emptyempty_stack([])
% push(+Item, +Stack, -NewStack) push(Item, Stack, [Item|Stack]).
%pop(+Stack, -Item, -NewStack)pop([Item|NewStack], Item, Stack).
Queues
Queue represented as a pair of lists (Front-Back)Back is always a variable
%empty_queue(?Queue) – true if the queue is emptyempty_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)).
Appending Difference Lists
Appending difference lists is very efficientappend_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.
Generate-and-Test
Popular (and sometimes efficient) way to write a program.
Goal :-Generator, - generates candidate solutionsTester. - verifies correct answers
Example: select/3
% select(+List, +Condition, -Element)
select(List, Condition, Element):-member(Element, List), - generates potential solutionscall(Condition). - verifies that the meet the condition
•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).
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]).
Example: NPR Puzzle
Sunday morning’s weekly puzzle on KQED this weekUsing 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).
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.
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).
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]),
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).
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:
peasomitduly
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.
top related