|
|||||||||||||||||||||
Унификацияструктур ⇐ ПредыдущаяСтр 4 из 4 true.
?- a(b,c(d,e(f,g))) = a(b,c(d,e(g,f))). false.
6.2 Другая форма унификации - междупеременной и константой.
Если термы содержат переменные, делается попытка присвоить значения переменным, так, чтобы оба терма стали идентичными. Если такое означивание переменных возможно, унификация успешна и значения переменных выдаются в качестве ответа.
В этом случае переменная просто «забирает» свое значение, что делает унификацию успешной. ?- Z = 1.Z = 1. ?- X = a.X = a. ?- 4 = Y.Y = 4. ?- 2+3 = X.X = 2+3. Интересно, что переменные могут находиться как слева, так и справа от знака '='. ?- X+2 = Y+3.false. ?- X+2 = 3+Y.X = 3,Y = 2.?- фрукты(яблоки, груши) = фрукты(X, груши). X = яблоки.
Вот примеры, когда несколько переменных одновременно связываются со своими значениями. ?- фрукты(X,Y) = фрукты(яблоки, груши). X = яблоки, Y = груши.
?- фрукты(яблоки, X) = фрукты(Y, груши). X = груши, Y = яблоки. 6.3 Переменные могут также унифицироватьсядруг с другом.
Каждая переменная имеет уникальное внутреннее представление Пролога. А когда две переменные унифицируются друг с другом, Пролог должны связать их с одним и тем же значением, что достигается, если расположить переменные в одном и том же месте памяти, т.е. присвоить им одинаковый адрес (или имя). ?- X = X.true. ?- X = Y.X = Y. Никаких значений переменные при этом не получают, но между ними устанавливается связь, таким образом, что в дальнейшем они будут выступать в качестве синонимов. Обратите внимание, что значение для X и Y в конце концов будет одно и то же.
Такие переменные называют сцепленными переменнымит.е. расположенными в одном и том же месте памяти. (Их нельзя путать со связанными , потому что связанная переменная означает то же, что "конкретизированная" или "означенная" переменная, то есть "переменная, получившая значение"), ?- фрукты(X, груши) = фрукты(Y, груши).X = Y.
Пролог запоминает факт, что переменная связана, и, если необходимо, вспоминает это позже, в процессе унификации. ?- X = Y, Y = hello.X = Y, Y = hello. ?- X = Y, a(Z) = a(Y), X = hello. X = Y, a(Z) = a(Y), X = hello. То, что мы видим, воспринимается Прологом как «запрос на утверждение»: а правда ли, что … ? Пролог просто повторяет ввод, сообщая, что, мол, как написано, так и есть, поскольку из имеющихся у него знаний по данному запросу никаких противоречий он не обнаружил. Вот ещё два примера. ?- a(Z) = a(Y), X = hello.Z = Y,X = hello.?- X = Y, Y = 3, write(X).3X = Y, Y = 3.
Последний пример очень важен для понимания процесса унификации. Он иллюстрируетглавное различие между унификациями переменных в Прологе Если у нас предварительно будет описан факт: пища(капуста). , то состоится такая унификация: ?- X = Y, пища(X), write(Y).капуста X = Y, Y = капуста. 6.4 Унификацияструктур
Когда две структуры, содержащие переменные, унифицируются друг с другом, переменные получают значения, которые делают обе структуры идентичными. Обратите внимание, что структура, связанная с переменной, может сама содержать переменные. ?- X = a(b,c).X = a(b,c) ?- a(b,X) = a(b,c(d,e)).X = c(d,e) ?- a(b,X) = a(b,c(Y,e)). X = c(Y, e).
В этих примерах надо увидеть, как отношения между переменными сохраняются. Они изменяются только в случае, как только происходят новые связывания переменных. ?- a(b,X) = a(b,c(Y,e)), Y = hello.X = c(hello, e)Y = hello К факту пища(капуста). добавим ещё один факт вкусно(яблоко). и попробуем унифицировать следующее выражение: ?- еда(X,Y) = Z, write(Z), nl, пища(X), вкусно(Y), write(Z). еда(_G541,_G542) еда(капуста,яблоко) X = капуста, Y = яблоко, Z = еда(капуста, яблоко).
Два раза отрабатывает оператор WRITE, но каждый раз по-разному !!! Но каждый раз он выдаёт те значения, которые получаются на текущей стадии унификации.
Здесь мы видим появление в ответе «странных» переменных. Дело в том, что такие обозначения в принятые SWI-Prolog’е для обозначения внутренних переменных, а именно: _Gnnn.
Если значение, назначенное переменной, вступает в противоречие в более поздних целях, то итоговая цель считается неуспешной. Например, ?- a(b,X) = a(b,c(Y,e)), X = hello.false. Здесь вторая цель получается неуспешной, поскольку не существует никакого значения Y, которое позволит hello унифицировать с c(Y,e). А вот такой пример даст успех. ?- a(b,X) = a(b,c(Y,e)), X = c(hello, e).X = c(hello, e)Y = hello
Если невозможно дать переменной никакого значения, то унификация получается неуспешной. ?- a(X) = a(b,c).false. ?- a(b,c,d) = a(X,X,d).false.
Последний пример терпит неудачу, потому что образец просит, чтобы первые два параметра были те же самые, и они - различны.
Вот два успешных примера
?- a(b,X,d) = a(X,X,d). X = b. ?- a(b,X,d) = a(X,b,d). X = b.
Пример неуспеха. ?- a(c,X,X) = a(Y,Y,b).false. Это происходит потому что, во-первых, сопоставление первого параметра связывает Y с c. Далее, второй параметр заставляет X и Y иметь то же самое значение, в нашем случае c. Третий параметр просит, чтобы X связали с b, а он уже связан к c. И, значит, никакое значение X и Y не позволит этим двум структурам унифицироваться.
Переменная без имени _ - особая переменная. Многократное её написание не подразумевает её одинаковые значения. ?- a(c,X,X) = a(_,_,b).X = b.
Подведем итог.
Унификация происходит явно, когда используется встроенный предикат равенства (=),
Упражнения
Предскажите результаты таких запросов унификации.
|
|||||||||||||||||||||
|