LING 388 Language and Computers Lecture 17 10/28/03 Sandiway FONG
Administrivia Next Time … Next Time … Computer Laboratory SBS 224 October 30th and November 4th
Last Time … We saw how to implement the filter: We saw how to implement the filter: All variables must be bound by an operator ( x) Blocks the example : *John hits(np(john),vp(v(hit),np(x))) The implementation was : The implementation was : filter(X) :- \+ ( variable(X,F), var(F) ). where: variable(X,F) is an np(x) finder (tree-walker, disjunctive form) and F reports on whether there is a dominating lambda in Xis an np(x) finder (tree-walker, disjunctive form) and F reports on whether there is a dominating lambda in X
Today’s Lecture Explore how to implement the second filter defined in Lecture 14 … Explore how to implement the second filter defined in Lecture 14 … Operator ( x) can only bind one variable np(x) Example: Example: *the cat that saw *the cat that [ NP e i ] saw [ NP e i ] (the cat)( x.x saw x) i.e. the cat that saw itself Pseudo-Logical Form: Pseudo-Logical Form: np(np(det(the),n(cat)),lambda(x,s(np(x),vp(v(saw),np(x))))) Note: the first filter (below) fails to rule this example out Note: the first filter (below) fails to rule this example out All variables must be bound by an operator
Today’s Lecture Another Example: Another Example: *the cat that John saw Mary (the cat)( x.John saw Mary) Pseudo-Logical Form: Pseudo-Logical Form: np(np(det(the),n(cat)),lambda(x,s(np(john),vp(v(saw),np(mary))))) vacuous x The first filter fails to rule this out The first filter fails to rule this out because there are no np(x) variables
Filter Implementation Filter 2: Filter 2: Operator ( x) can only bind one variable Basic Implementation Idea: Basic Implementation Idea: Look for structure lambda(x,Y) Check Y to see that there is at most one np(x) inside
Filter Implementation Question: Question: How to look for lambda(x,Y) Answer: Answer: from Lectures 15 and 16, we have that code available already Use the tree-walker (disjunctive form) operator/1 operator(X) holds if there is a lambda expression in X
Filter Implementation Code: Code: operator(lambda(x,_)). operator(X) :- X =.. [F,A1,A2],X =.. [F,A1,A2], operator(A1).operator(A1). operator(X) :- X =.. [F,A1,A2],X =.. [F,A1,A2], operator(A2).operator(A2). operator(X) :- X =.. [F,A],X =.. [F,A], operator(A).operator(A). Predicate operator(X) holds if X contains lambda(x,_) inside Notes: 1.All clauses except for the 1st recursively call operator/1 on a subtree 2.Successful stopping condition is when we match with lambda(x,_)
Filter Implementation Step 1: Modify operator/1 to add in a sub-call to check for a variable Step 1: Modify operator/1 to add in a sub-call to check for a variable operator(lambda(x,Y)). operator(X) :- X =.. [F,A1,A2], operator(A1). operator(X) :- X =.. [F,A1,A2], operator(A2). operator(X) :- X =.. [F,A], operator(A). operator(lambda(x,Y)):- variable(Y). operator(X) :- X =.. [F,A1,A2], operator(A1). operator(X) :- X =.. [F,A1,A2], operator(A2). operator(X) :- X =.. [F,A], operator(A).
Filter Implementation Re-using the definition of variable/1 from last time … Re-using the definition of variable/1 from last time … operator/1 holds if lambda(x, … np(x) …) exists operator(lambda(x,Y)):- variable(Y). operator(X) :- X =.. [F,A1,A2], operator(A1). operator(X) :- X =.. [F,A1,A2], operator(A2). operator(X) :- X =.. [F,A], operator(A). 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).
Filter Implementation Now, operator/1 admits both: Now, operator/1 admits both: lambda(x, … np(x) …) *lambda(x, … np(x) … np(x) … ) So: So: we need to modify variable/1 to count and fail when it finds two (or more) np(x)s Basic Idea: Basic Idea: Use a conjunctive tree-walker We need to count, so we need make sure we visit every node Disjunctive tree-walking doesn’t work because it has a choice of which branch to take when faced with binary branching
Filter Implementation Question: Question: How to implement a counter? Answer: Answer: Use the extra argument device to pass around a counter which gets incremented when needed Simpler Answer (for counting up to two only): Simpler Answer (for counting up to two only): Use the feature setting mechanism we used to detect lambda in Lecture 16 Instantiate the extra argument to be a constant, e.g. one, when we find out first np(x) When we see an np(x), check to see if the extra argument is still a variable or one - fail in the latter case [For yet another solution suggested in class: see appendix] [For yet another solution suggested in class: see appendix]
Filter Implementation Basic tree-walker (conjunctive form): Basic tree-walker (conjunctive form): visit(X) :- X =.. [F,A1,A2], visit(A1), visit(A2). visit(X) :- X =.. [F,A], visit(A). visit(X) :- atom(X). s npvp vnp detn theman saw john
Filter Implementation Step 1: Add a clause for np(x) Step 1: Add a clause for np(x) visit(np(x)). visit(X) :- X =.. [F,A1,A2], visit(A1), visit(A2). visit(X) :- X =.. [F,A], visit(A). visit(X) :- atom(X). visit(X) :- X =.. [F,A1,A2], visit(A1), visit(A2). visit(X) :- X =.. [F,A], visit(A). visit(X) :- atom(X).
Filter Implementation Step 2: Add an extra argument Step 2: Add an extra argument visit(np(x)). visit(X) :- X =.. [F,A1,A2], visit(A1), visit(A2). visit(X) :- X =.. [F,A], visit(A). visit(X) :- atom(X). visit(np(x),F). visit(X,F) :- X =.. [_,A1,A2], visit(A1,F), visit(A2,F). visit(X,F) :- X =.. [_,A], visit(A,F). visit(X,F) :- atom(X).
Filter Implementation Step 3: Modify clause for np(x) to test and set the extra argument Step 3: Modify clause for np(x) to test and set the extra argument visit(np(x),F). visit(X,F) :- X =.. [_,A1,A2], visit(A1,F), visit(A2,F). visit(X,F) :- X =.. [_,A], visit(A,F). visit(X,F) :- atom(X). visit(np(x),F) :- var(F), F = one. visit(X,F) :- X =.. [_,A1,A2], visit(A1,F), visit(A2,F). visit(X,F) :- X =.. [_,A], visit(A,F). visit(X,F) :- atom(X).
Filter Implementation Problem: Problem: What happens if we see a 2nd np(x)? 1st clause will correctly block, but np(x) also matches the 3rd clause visit(np(x),F) :- var(F), F = one. visit(X,F) :- X =.. [_,A1,A2], visit(A1,F), visit(A2,F). visit(X,F) :- X =.. [_,A], visit(A,F). visit(X,F) :- atom(X). Succeeds for the 2nd np(x) But we want to prevent this!
Filter Implementation Step 4: Add a pre-condition to clause 3 to block np(x) from matching X Step 4: Add a pre-condition to clause 3 to block np(x) from matching X visit(np(x),F) :- var(F), F = one. visit(X,F) :- X =.. [_,A1,A2], visit(A1,F), visit(A2,F). visit(X,F) :- \+ X = np(x), X =.. [_,A], visit(A,F). visit(X,F) :- atom(X). Pre-condition prevents X = np(x) from succeeding with this clause Note: = and == can be used interchangeably here because the test is in the scope of the negation operator \+. X \== np(x) is possible as well
Filter Implementation Step 5: Rename visit/2 as lt2vars/2 (less than 2 variables) to reflect the revised semantics Step 5: Rename visit/2 as lt2vars/2 (less than 2 variables) to reflect the revised semantics lt2vars(np(x),F) :- var(F), F = one. lt2vars(X,F) :- X =.. [_,A1,A2], lt2vars(A1,F), lt2vars(A2,F). lt2vars(X,F) :- \+ X = np(x), X =.. [_,A], lt2vars(A,F). lt2vars(X,F) :- atom(X). operator(lambda(x,Y)):- lt2vars(Y,_). operator(X) :- X =.. [F,A1,A2], operator(A1). operator(X) :- X =.. [F,A1,A2], operator(A2). operator(X) :- X =.. [F,A], operator(A).
Filter Implementation Filter 2: Filter 2: Operator ( x) can only bind one variable Implementation: Implementation: filter2(X) :- operator(X). almost but not quite correct, do you see when it fails to work? see Computer Laboratory to come … Use: Use: ?- s(X,Sentence,[]), filter2(X). X is the phrase structure returned by the DCG Sentence is the input sentence encoded as a list filter/2 is a condition on representation
Filter Implementation: Summary Summary: Start with a lambda(x,Y) finder that calls visit(Y) Make visit/1 a conjunctive tree-walker 1. We’ll be interested in making np(x) a special case Add a clause for np(x) to visit/1 2. We’ll need to count during the search Add an extra argument to visit/1 => visit/2 3. We’ll count when we match the special case np(x) Modify clause for np(x) to test and set the extra argument 4. Prevent np(x) from matching any clause other than the special case Modify the unary branching clause, i.e. when X is F(A), to block it from matching np(x) 5. We have new semantics for the conjunctive tree-walker Rename it!
Bijection Principle Implementation Bijection Principle (Koopman): Bijection Principle (Koopman): Operators and variables must be in one-to-one correspondence Filters: Filters: (filter1) All variables must be bound by an operator ( x) (filter2) Operator ( x) can only bind one variable Implementation: Implementation: bijectionPrinciple(X) :- filter(X), filter2(X). Use: Use: ?- s(X,Sentence,[]), bijectionPrinciple(X). X is the phrase structure returned by the DCG Sentence is the input sentence encoded as a list
Tree-Walker Summary Question: Question: Which tree-walker to use? Answers: Answers: Need to find some element in the tree? Use the disjunctive form E.g. variable(X) holds if there exists some np(x) in XE.g. variable(X) holds if there exists some np(x) in X Need to count the number of occurrences of some element in the tree? Use the conjunctive form E.g. lt2vars(X,_) holds there are zero or one occurrences of np(x) in XE.g. lt2vars(X,_) holds there are zero or one occurrences of np(x) in X
Appendix
Filter Implementation Revisited Question: Question: How to implement a counter (to count up to two)? Answer (in preceding slides): Answer (in preceding slides): Use an extra argument in a conjunctive tree-walker; test and set the argument 1st time around Another Solution: Another Solution: Use negation Advantage: no need for extra argument
Filter Implementation Revisited Add a test to confirm that if variable/1 holds for one branch, it cannot hold for the other branch: Add a test to confirm that if variable/1 holds for one branch, it cannot hold for the other branch: variable(np(x)). variable(X) :- X =.. [F,A1,A2], variable(A1) -> \+ variable(A2) ; variable(A2). variable(X) :- X =.. [F,A], variable(A). Truth Table: Truth Table: variable(X)variable(A1)variable(A2) F (False) FF F T (True) T TFT TTF Prolog’s “if then else” construct: -> ;
Exercise 1: Relative Clauses Example: Pseudo-Logical Form for *the cat that saw: Example: Pseudo-Logical Form for *the cat that saw: np det the n cat lambda xs np vp vx sawx TF TT F F variable(X) fails for s