CS 541 Lecture -*- Outline -*- * Unification ** the problem ------------------------------------------ THE PROBLEM How to make "guess" when matching existential queries vs. universally quantified rules? What are we guessing? What determines that? ------------------------------------------ ... a common instance ... a substitution *** two further problems **** the variable convention ------------------------------------------ TWO FURTHER PROBLEMS Problem 1: good (tree Left Right). % fact ?- good (tree Right Left). % query Is there a common instance? Solution: ------------------------------------------ ... "moo" note: since scope of variables is limited to a clause, always comparing two terms with different variables (may look the same to you, but internally different). so we first rename the fact to ... good (tree Left1 Right1). **** generality and most general unifiers ------------------------------------------ FURTHER PROBLEM 2 Example (member Y (Y::nil)). % fact ?- (member Z (X::nil)). % query What substitution to use? s1 = {Y |-> 1, Z |-> 1, X |-> 1} s2 = {Y |-> 2, Z |-> 2, X |-> 2} s3 = {Y |-> 3, Z |-> 3, X |-> 3} ... ------------------------------------------ we don't want to choose, want something that captures all of this what would that be? ------------------------------------------ GENERALITY def: a term T is more general than V iff example: (foo X X X) vs. (foo 3 3 3) def: T is an alphabetic variant of V iff ------------------------------------------ ... V is an instance of T, but T is not an instance of V. Q: which is more general? ... both are instances of each other. Q: is (member Y (Y::nil)) an alphabetic variant of (member Z (X::nil))? So what we seek is that substitution that gives the most general common instance. *** unifier ------------------------------------------ UNIFIER def: a unifier for terms T and V is a def: T and V unify iff there is a unifier for T and V. def: most general unifier (mgu) of T and V is unifier for T and V that generates the most general common instance. ------------------------------------------ ... substitution s such that s[[T]] = s[[V]]. a unifier makes two terms identical. it determines a common instance (by applying the substitution). mgu is unique up to alphabetic variants what makes logic programming work is that can compute mgu linear in size of the smallest term ------------------------------------------ UNIFIER EXAMPLES sig unifier-examples. kind thing type. type algol thing. type star thing -> o. type g A -> int -> o. type eq A -> A -> o. module unifier-examples. star algol. g X 3. eq X X. $ tjsim unifier-examples [unifier-examples] ?- star X. ?- g 4 Y. ?- eq Y Z. ------------------------------------------ ... X = algol % (star X) unifies with (star algol) % by substituion s[[X]]=algol ... Y = 3 % and (X = 4) not shown ... Z = Q Y = Q % and X = Q is not shown. % they can all be anything as long as it's the same. Teyjus prints Y = Z and Z = Z. using a substition that maps X to Z, which makes the common instance be (eq Z Z). What it prints is not exactly a substitution, because Z appears in both the domain and range (it's the result of applying the substitution to all the free vars in the query) **** exercises ------------------------------------------ FOR YOU TO DO Compute the mgu, if any, of each pair: (member 3 3::nil) (member X (X::nil)) (member Y (3::nil)) (member X (X::nil)) (member 3 (4::nil)) (member X (X::L)) (length (3::nil) N) (member X (X::L)) (member X (X::L)) (member (3::nil) N) (member X (X::L)) (member Y ((tree (Y::nil) (Q::nil))::M)) (diff X X) (diff (1::2::Y) Y) ------------------------------------------ The last two do not unify because of the occurs check suppose we say that they unify with s[[Y]] = (1::2::Y) then s is not a proper substitution (as Y occurs in the range). (so what? see below) **** occurs check def: an occurs check ensures that unifier does not map a variable to a term in which that variable appears. Q: From the examples, why would we want the occurs check? to prevent the unification of terms that don't have common instances. many practical prolog implementations omit the occurs check, but for not very good reasons; unification is linear *even with* the occurs check. but lambda prolog has it! This has advantages for programming, and especially for meta-programming, as it makes type inference, for example, work. (why, because you want to use \Prolog's logical variables as logical variables in target language.)