Call(X)
Передбачається, що X конкретизований термом, який може бути інтерпретований як цільове твердження. Цільове затвердження call(X) вважається погодженим, якщо спроба довести узгодженість X завершується успіхом. Цільове твердження call(X) не узгоджується з базою даних, якщо спроба довести узгодженість X закінчується невдачею. На перший погляд цей предикат може здатися зайвим, оскільки, природно, виникає питання: чому аргумент call не може бути записаний безпосередньо як цільове твердження? Наприклад, цільове твердження
…, саll(належить(a,Х)),….
завжди може бути замінене наступним:
…, належить(а,X),….
Проте якщо ми створюємо цільові твердження, використовуючи предикат '=..' або йому подібні, то можливі звернення до цільових тверджень, функтори яких невідомі на момент вводу програми в Пролог-систему. Так, наприклад, у означенні предиката consult треба мати можливість розглядати будь-який терм, прочитаний після ?-, як цільове твердження. Припускаючи, що Р, X і Y конкретизовані функтором і аргументами відповідно, можна використати call таким чином:
…, Z=..[P,X,Y], call(Z),….
Останній фрагмент програми можна розглядати як спосіб вираження звернення до цільового твердження наступного вигляду:
…,Р(Х,Y),….
яке у рамках стандартної версії Прологу, що розглядається в цьому курсі, синтаксично некоректне. Проте деякі версії мови Пролог допускають використання змінної як функтора цільового твердження.
Not(X)
Передбачається, що X конкретизований термом, який може бути інтерпретований як цільове твердження. Цільове затвердження not(X) вважається погодженим з базою даних, якщо спроба довести узгодженість X закінчується невдачею. Цільове твердження not(X) вважається неузгодженим, якщо спроба довести узгодженість X успішно завершується. У цьому плані предикат not дуже схожий на call, за тим виключенням, що узгодженість або неузгодженість аргументу, що розглядається як цільове твердження, приводить до протилежного результату.
Чим відрізняються наступні два запитання?
/* 1 */ ?— належить(Х,[а,b,c]), write(X).
/* 2 */ ?— not(not(належить(Х,[а,b,c]))), write(X).
Може здатися, що між ними немає жодної різниці, оскільки в запитанні 2 належить(Х,[а,b,c]) узгоджується, тому not(належить(Х,[а,b,c])) не узгоджується і not(not(належить(X,[a,b,c]))) узгоджується. Це правильно лише часткове. В результаті першого запитання буде надрукований атом 'а', а в результаті другого — неконкретизована змінна. Розглянемо, що відбувається при спробі довести узгодженість першого цільового твердження з другого запитання:
1. Цільове твердження належить узгоджується, і X конкретизується значенням а.
2. Робиться спроба довести узгодженість першого цільового затвердження not, яка закінчується невдачею, оскільки цільове твердження належить, що є його аргументом, узгоджується з базою даних. Тепер згадаємо, що, коли цільове твердження не узгоджується, всі конкретизовані змінні, такі як X в нашому прикладі, повинні тепер «забути», що вони означали досі. Отже, X стає неконкретизованою.
3. Робиться спроба довести друге цільове твердження not, і ця спроба закінчується успіхом, оскільки його аргумент (not(належить(...))) не погоджений. Змінна X залишається неконкретизованою.
4. Робиться спроба виконати цільове твердження write з неконкретизованим значенням X.
47.Рівність
X=Y
Коли Пролог зустрічає цільове твердження X=Y, то намагається зробити X і Y рівними, зіставляючи їх один з одним. Якщо зіставлення можливе, то цільове твердження вважається погодженим (а X і Y, можливо, стають більше конкретизованими). Інакше цільове твердження вважається неузгодженим. Предикат рівне означений таким чином, начебто мав місце факт
X=X.
Переконайтеся, що ви розумієте, як це означення працює.
X\=Y
Предикат '\=' є протилежним по відношенню до предиката '=' з точки зору узгодженості з базою даних. Це означає, що X\=Y погоджене, якщо X=Y не погоджене, і навпаки. Якщо цільове твердження X\=Y погоджене.
Предикат '==' виконує значно строгішу перевірку на рівність, ніж предикат '=' Це означає, що якщо X==Y виконується, то і тим більше виконується X=Y. А обернений висновок не завжди має місце. Відмінність '==' полягає в тому, що він строгіший до змінних. Предикат '=' припускає, що неконкретизована змінна може дорівнювати чому завгодно, оскільки вона порівнюється з чим завгодно. З іншого боку, предикат '==' припускає, що неконкретизована змінна може дорівнювати іншій неконкретизованій змінній, лише коли вони вже зчеплені одна з одною. Інакше перевірка на рівність закінчується невдачею. Таким чином, можливий наступний діалог:
?— X==Y.
false
?- X==X.
X=_23/*або true */.
Х\==Y
Цей предикат знаходиться в такому ж відношенні з '==', як '\=' з '='. Це означає, що цільове твердження, що містить цей предикат, погоджується в точності тоді, коли цільове твердження з '==' не погоджується, і навпаки.
48.Ввід і вивід даних