240 likes | 325 Vues
LING 388 Language and Computers. Lecture 16 10/23 /03 Sandiway FONG. Administrivia. Review. Last time, we discussed how to implement the filter: All variables must be bound by an operator ( l x ) To block examples like: *John hit s(np(john),vp(v(hit),np( x ))) Implementation:
E N D
LING 388Language and Computers Lecture 16 10/23/03 Sandiway FONG
Review • Last time, we discussed how to implement the filter: • All variables must be bound by an operator (lx) • To block examples like: • *John hit s(np(john),vp(v(hit),np(x))) • Implementation: • Based on a tree-walker (disjunctive form) that searched and returned true if a variable np(x) and an accompanying operator lx could be found in phrase structure
Review: Disjunctive Tree-Walker • variable(np(x)). • variable(X) :- • X =.. [F,A1,A2], • variable(A1). • variable(X) :- • X =.. [F,A1,A2], • variable(A2). • variable(X) :- • X =.. [F,A], • variable(A). • Given some tree structure X: • variable(X) holds if there is some np(x) in X • Clause by clause: • Matches np(x) (and stops) • Recursively calls variable(A1) when X is of form F(A1,A2) • Recursively calls variable(A2) when X is of form F(A1,A2) • Recursively calls variable(A) when X is of form F(A)
Review: Disjunctive Tree-Walker • variable(np(x)). • variable(X) :- • X =.. [F,A1,A2], • variable(A1). • variable(X) :- • X =.. [F,A1,A2], • variable(A2). • variable(X) :- • X =.. [F,A], • variable(A). Notes: Every clause for variable/1 except for the first recursively calls variable/1 on a subtree Only way variable/1 can terminate and succeed is if it terminates in the 1st clause
s np vp v np john hit x Review: Disjunctive Tree-Walker • Worked example for *John hit [NPe] • Prolog query: • ?- variable(s(np(john),vp(v(hit),np(x)))).
Review: Disjunctive Tree-Walker • variable(np(x)). • variable(X) :- • X =.. [F,A1,A2], • variable(A1). • variable(X) :- • X =.. [F,A1,A2], • variable(A2). • variable(X) :- • X =.. [F,A], • variable(A). Example of derivation: ?- variable(s(np(john),vp(v(hit),np(x)))). ?- variable(np(john)) ?- variable(john). FAILS ?- variable(vp(v(hit),np(x))). ?- variable(v(hit)). ?- variable(hit). FAILS ?- variable(np(x)). SUCCEEDS Note: ?- variable(s(np(john),vp(v(hit),np(mary)))). FAILS ?-variable(np(np(det(the),n(cat)),lambda(x,s(np(i),vp( v(saw),np(x)))))). SUCCEEDS
Review: Disjunctive Tree-Walker • Operator/1 is a lx, i.e. lambda(x,_), in the phrase structure • operator(lambda(x,_)). • operator(X) :- • X =.. [F,A1,A2], • operator(A1). • operator(X) :- • X =.. [F,A1,A2], • operator(A2). • operator(X) :- • X =.. [F,A], • operator(A). • Examples: • ?- operator(s(np(john),vp(v(hit),np(x)))). • No • ?- operator(s(np(john),vp(v(hit),np(mary)))). • No • ?-operator(np(np(det(the),n(cat)), • lambda(x,s(np(i),vp(v(saw),np(x)))))). • Yes
Review: Filter Implementation • Filter: • All variables must be bound by an operator (lx) • Implementation (Initial try): • Using predicates: • variable(X) np(x) finder • operator(X) lambda(x, … ) finder • Define: • filter(X) :- variable(X) -> operator(X). • To be read as: • filter(X) holds if operator(X) holds when variable(X) holds • Note: -> is the Prolog built-in “if … then” construct
Review: Filter Implementation • Use: • ?- s(X,Sentence,[]), filter(X). • X is the phrase structure returned by the DCG • Sentence is the input sentence encoded as a list • Problem with definition: • filter(X) :- variable(X) -> operator(X). • Semantics: • Holds if there is some variable that has an accompanying operator • Question: • What happens if we have two variables only one of which is properly bound? • Example: filter(X) fails to exclude … • *the cat that I saw hit *the cat that I saw [NP e] hit [NP e] s(np(np(det(the),n(cat)),lambda(x,s(np(i),vp(v(saw),np(x))))),vp(v(hit),np(x))) ?
s lambda x np(x) Filter Implementation: Part 2 • A better (i.e. more faithful) implementation… • When we find np(x), we check nodes dominating np(x) for signs of lx If we find lambda, we know np(x) is bound by that operator • Implementation Question: • We know predicate variable/1 finds np(x) • How do we modify it to report when it finds lambda as well? variable/1 true lambda(x, … )
s lambda x np(x) Filter Implementation: Part 2 • Idea: • Modify predicate variable/1 to produce a sign of some sort if it sees a lambda on the way down to np(x) • Note: if lambda doesn’t dominate np(x), we don’t want a sign • Use the extra argument mechanism from previous lectures for feature passing (person/number agreement) • We’ll pass an arbitrary feature, call it f, if we see an appropriate lambda F = f variable(X,F) true lambda(x, … ) F = f F unbound
Filter Implementation: Part 2 • variable(np(x),_). • variable(X,F) :- • X =.. [_,A1,A2], • variable(A1,F). • variable(X,F) :- • X =.. [_,A1,A2], • variable(A2,F). • variable(X,F) :- • X =.. [_,A], • variable(A,F). • variable(np(x)). • variable(X) :- • X =.. [F,A1,A2], • variable(A1). • variable(X) :- • X =.. [F,A1,A2], • variable(A2). • variable(X) :- • X =.. [F,A], • variable(A). • We need to modify variable/1 so that we can pass information indicating the presence or absence of lambda as we traverse the tree • We do this by first adding a 2nd argument F to variable/1
Filter Implementation: Part 2 • variable(np(x),_). • variable(X,F) :- • X =.. [_,A1,A2], • variable(A1,F). • variable(X,F) :- • X =.. [_,A1,A2], • variable(A2,F). • variable(X,F) :- • X =.. [_,A], • variable(A,F). • variable(np(x),_). • variable(lambda(x,Y),f) :- • variable(Y,_). • variable(X,F) :- • X =.. [_,A1,A2], • variable(A1,F). • variable(X,F) :- • X =.. [_,A1,A2], • variable(A2,F). • variable(X,F) :- • X =.. [_,A], • variable(A,F). • step 2: add a clause to detect and report the presence of lambda
Filter Implementation: Part 2 • Notes: • Every clause for variable/2 except for the first one recursively calls variable/2 on a subtree • Only way variable/2 can succeed is if it terminates in the 1st clause • When variable/2 holds, we can inspect the 2nd argument to see if along the way it found a lambda expression as well • This is signaled by the f feature • The 2nd clause exclusively sets the 2nd argument • variable(np(x),_). • variable(lambda(x,Y),f) :- • variable(Y,_). • variable(X,F) :- • X =.. [_,A1,A2], • variable(A1,F). • variable(X,F) :- • X =.. [_,A1,A2], • variable(A2,F). • variable(X,F) :- • X =.. [_,A], • variable(A,F).
s lambda x lambda x np(x) Filter Implementation: Part 2 Underscore (don’t care variable) because we’re not interested in reporting multiple lambdas dominating np(x) • variable(np(x),_). • variable(lambda(x,Y),f) :- • variable(Y,_). • variable(X,F) :- • X =.. [_,A1,A2], • variable(A1,F). • variable(X,F) :- • X =.. [_,A1,A2], • variable(A2,F). • variable(X,F) :- • X =.. [_,A], • variable(A,F). sets 2nd argument to be f sets 2nd argument to be f
Filter Implementation: Part 2 • variable(np(x),_). • variable(lambda(x,Y),f) :- • variable(Y,_). • variable(X,F) :- • X =.. [Y,A1,A2], • \+ Y = lambda, • variable(A1,F). • variable(X,F) :- • X =.. [Y,A1,A2], • \+ Y = lambda, • variable(A2,F). • variable(X,F) :- • X =.. [_,A], • variable(A,F). Since clause 2 must set f exclusively, we must prevent lambda from matching these two clauses
Filter Implementation: Part 2 • Use: • filter(X) :- variable(X,F), F == f. • Note: • Filter/1 holds if variable/2 holds and the value reported in the 2nd argument F is identical to f • We use identity (==) instead of unification (=) because we’re testing whether F has been bound to a value
Identity (==) • == • is a Prolog built-in taking two arguments • compares but does not perform unification • Note: • = attempts to unify its arguments • Hence, neither of the clauses • filter(X) :- variable(X,F), F = f. • filter(X) :- variable(X,f). will work for our purposes • Examples: • ?- abc == abc. Yes ?- abc = abc. Yes • ?- X == abc. No ?- X = abc. Yes • ?- X = abc, X == abc. Yes ?- X = abc, X = abc. Yes • ?- X == Y. No ?- X == Y. Yes
Filter Implementation: Part 3 • Definition: • filter(X) :- variable(X,F), F == f. • Is still not quite right … • filter(X) holds if there exists one valid variable/lambda pair in X • However … • This fails to block the case where there may be more than one variable, only one of which has a valid accompanying lambda expression, as in: • *the cat that I saw hit • s(np(np(det(the),n(cat)),lambda(x,s(np(i),vp(v(saw),np(x))))), vp(v(hit),np(x))) In other words, variable/1 is true for the whole expression because it finds the lambda/np(x) pair
Filter Implementation: Part 3 • Solution: • Want filter/1 to hold if there are no configurations for which variable(X,F) holds and F remains unbound • New Definition: • filter(X) :- \+ ( variable(X,F), var(F) ). • to be read as: • filter(X) holds if it’s not the case that when variable(X,F) succeeds and F is uninstantiated • Note: • var(F) is a Prolog built-in that holds if F is uninstantiated, i.e. a Prolog variable
var/1 • var(X) • is a Prolog built-in that takes one argument • holds if X is a variable at the time of the call to var/1 • Examples: • ?- var(X). Yes • ?- var(f). No • ?- X=f, var(X). No • ?- var(X), X = 2. Yes … fact that X is no longer a variable after unifying with 2 doesn’t change the semantics of var/1
Summary: Filter Implementation • Summarizing: • filter(X) :- \+ ( variable(X,F), var(F) ) implements filter: • All variables must be bound by an operator (lx) • variable(X,F) • is a disjunctive tree-walker that looks for np(x) • also looks for lambda(x,Y) where Y contains a variable np(x) • returns f as the value of F if it finds the lambda above • variable(X,F), var(F) • will succeed if there is an np(x) without an accompanying lambda expression • \+ ( variable(X,F), var(F) ) • will succeed if there aren’t any np(x)s without an accompanying lambda expression
Next Time … • We’ll look at how to implement the other constraint mentioned in Lecture 14: • All variables must be bound by an operator (lx) • Operator (lx) can only bind one variable