Типы данных или предопределенные объекты
ВВЕДЕНИЕ
PROLOG (PROgramming in LOGic - "логическое программирование") - язык логического программирования, используемый для решения задач, сводимых к объектам и отношениям между ними; позволяет разрабатывать на основе ПЭВМ экспертные системы, базы знаний и системы обработки естественного языка.
Язык PROLOG разработан в 1971 году Аленом Кольмеро и его коллегами из Марсельского университета (Франция).
Две самых отличительных черты языка PROLOG - это его способность к сравнению выражений (сопоставлению фактов) и внутренняя реляционная база данных. Используя правила своей внутренней базы
данных и аппарат сравнения фактов, PROLOG может выдавать ответы на поставленные в логической форме вопросы.
При программировании на Прологе значительно упрощается описание решений, и программист имеет возможность заниматься непосредственно задачей. То есть описанием ответа на вопрос ЧТО? делать, а не КАК? искать решение.
Прологу присущ ряд свойств, которыми не обладают традиционные языки программирования. К таким свойствам относятся механизм вывода с поиском и возвратом (бектрекинг), встроенный механизм сопоставления с образом (унификация), и простая, но выразительная структура данных с возможностью ее изменения. Пролог отличает единообразие программ и данных, что позволяет менять программу во время ее работы. Декларативность языка позволяет понимать программу, не отслеживая динамику ее выполнения.
Cистема Turbo-PROLOG - технологична. На уровне объектных модулей Turbo-PROLOG совместим с такими языками как Turbo-Pascal, Turbo-C, Turbo-ASM (турбо-ассемблер) и использует стандартную графическую библиотеку функций фирмы Borland.
ПРОГРАММИРОВАНИЕ НА ПРОЛОГЕ
Основные понятия
Пролог - язык программирования, используемый для решения задач, сводимых к объектам и отношениям между ними. Программирование на языке Пролог состоит из следующих этапов:
1. Объявление некоторых фактов об объектах и отношениях между ними.
2. Определение правил, описывающих объекты и отношения.
+------------------------------------------------------+
¦ Программа на Прологе состоит из множества ¦
¦ утверждений, каждое из которых является фактом о ¦
¦ заданной информации, либо правилом, указывающим, ¦
¦ как решение связано с заданными фактами и каким ¦
¦ образом его можно вывести из них. ¦
¦ Совокупность фактов и правил в Прологе ¦
¦ называется базой данных. ¦
+------------------------------------------------------+
3. Формулировки вопросов об объектах и отношениях между ними, т.е. формирование запроса к созданной ранее базе данных.
По сути, Пролог-система позволяет использовать ЭВМ как хранилище фактов и правил, и предоставляет механизм, позволяющий делать выводы, переходя от одних фактов к другим.
Именем отношения между объектами является ПРЕДИКАТ.
Например: name_predicates(О1,О2, ... ,ОN).
Это имя, которое записывается перед круглыми скобками. Вся запись типа name(O1,O2,.,O3) называется предикатной структурой
или предикатным термом. Предикат является функтором некоторой структуры.
Представление Пролог-программ в виде предикатных структур и предикатных термов обладает многими достоинствами, главное из которых - это единообразие записи функций и процедур.
ТЕРМ - единообразная структура для описания данных и предикатов на языке Пролог.
Термы в Турбо-Прологе могут быть в двух формах:
1. Предикатные термы.
2. Термы-предикаты внутренней и внешней баз данных.
По структуре термы баз данных не отличаются от предикатных термов.
+------------------------------------------------------+
¦ В Турбо-Прологе обязательно объявление всех ¦
¦ термов в разделе [GLOBAL] PREDICATES, [GLOBAL] ¦
¦ DATABASE и их компонент в разделе [GLOBAL] ¦
¦ DOMAINS. В скомпилированной Турбо-Пролог-программе ¦
¦ возможно производить модификацию только термов баз ¦
¦ данных. Это сделано с целью повышения ¦
¦ быстродействия Пролог-программ и их компиляции, а ¦
¦ также введение дополнительного контроля за типами ¦
¦ переменных. Все это существенно отличает Турбо- ¦
¦ Пролог от других версий языка. ¦
+------------------------------------------------------+
Все термы могут быть объявлены как детерминированные или недетерминированные.
Недетерминироваными являются предикаты, которые могут вызываться на пересогласование с базой данных при бектрекинге (возврате по несогласованию следующего предиката). Детерминированные предикаты при возврате пропускаются (не пересогласовываются с базой данных).
+------------------------------------------------------+
¦ Детерминированные предикаты занимают меньше ¦
¦ места в памяти ЭВМ, после компиляции и выполняются ¦
¦ быстрее. ¦
+------------------------------------------------------+
Все встроенные предикаты из системной библиотеки и предикаты-процедуры, созданные при помощи других языков программирования
и скомпонованные в единый рабочий модуль, выполняются как детерминированные. Кроме того, все предикаты по умолчанию рассматриваются компилятором как детерминированные. Существует также стандартный предикат check_determ для проверки предикатов на детерминированность.
Для объявления принадлежности предиката к той или другой группе в Турбо-Прологе существуют служебные слова determ и nondeterm, с помощью которых вы можете определить предикат.
Предикат также будет рассматриваться компилятором как детерминированный, если в его выражении (clause) присутствует знак отсечения - !.
Объекты данных в Прологе также называются термами. Терм может быть константой, переменной, списком или составным термом (структурой). Более точное определение терма для Турбо-Пролога изображено на рис.1.
+---------------------+
¦ Терм ¦
+---------------------+
+-----------------+
+-------------------------+ +-------------------------+
¦ Термы (предикаты) ¦ ¦ ¦
¦ внутренней динамической ¦ ¦ Объекты (домены), ¦
¦ базы данных, ¦ ¦ ¦
¦ описывается в разделе ¦ ¦ описывается в разделе ¦
¦ [GLOBAL] DATABASE ¦ ¦ [GLOBAL] DOMAINS ¦
¦ текста программы ¦ ¦ текста программы ¦
+-------------------------+ +-------------------------+
+----------------------------------------------+
+-----------+ +------------+ +--------+ +------------+
¦ Константы ¦ ¦ Переменные ¦ ¦ Списки ¦ ¦ Стртуктуры ¦
+-----------+ +------------+ +--------+ +------------+
+-------+ +-------+ ¦+--------------+
¦ Числа ¦ ¦ Атомы ¦ +¦ Анонимные ¦
+-------+ +-------+ ¦+--------------+
¦+-------+ +--------++---------+ ¦+--------------+ +-----------+
+¦ Целые ¦ ¦ Строки ¦¦ Символы ¦ +¦ Определяемые +-¦ Cвязанные ¦
¦+-------+ +--------++---------+ +--------------+¦+-----------+
¦+----------------+ ¦+-----------+
+¦ Действительные ¦ +¦ Свободные ¦
+----------------+ +-----------+
Рис. 1. Виды термов Турбо-пролога
ФАКТ - это предикат, не определяемый через другие предикаты или самого себя.
Зададим несколько фактов на естественном языке, в "русифицированной" версии Пролога и на Турбо-Прологе:
-----------------------------------------------------------------+
Естеств.язык. ¦Русифицир.Турбо-Пролог¦Турбо-Пролог |
---------------------+----------------------+--------------------+
Сократ - человек. ¦человек(сократ). ¦man(socrat). |
Ольга любит цветы. ¦любит(ольга,цветы). ¦likes(olga,flauers).|
Петр дает Ивану книгу¦дает(петр,ивану,книгу)¦give(petr,ivan,book)|
-----------------------------------------------------------------+
Отметим ряд правил, которых нужно придерживаться, чтобы описывать факты без ошибок:
1. Имена всех объектов должны начинаться с маленькой буквы
(т.к. с большой буквы начинаются переменные).
2. На первом месте (в качестве функтора) записывается отношение, а затем в скобках следует список имен объектов, вступающих
в данное отношение. Объекты разделяются запятыми.
3. В конце факта ставится точка.
ПРАВИЛО - это предикат, определяемый через другие предикаты или самого себя.
Рассмотрим правило на русском языке:
Х является сестрой У, если
Х является женщиной и
Х и У имеют общих родителей.
Как видим, правило - это некоторое общее утверждение об объектах и отношениях между ними. Так как правила должны обладать общностью, в них обычно используются переменные (имена, начинающиеся с большой буквы). В Турбо-Прологе правило состоит из заголовка и тела правила, разделяемых специальным символом.
Русифиц. Турбо-Пролог: Tурбо-Пролог: является_сестрой(Х,У):- is_sister(X,Y) if женщина(Х), woman(X) and
родители(X,F,M), parants(X,F,M) and
родители(У,F,M). parants(Y,F,M).
В правилах на Турбо-Прологе допускается использовать ':-' вместо 'if' , ',' вместо 'and' и ';' вместо 'or'. Это сделано для соответствия с другими версиями Пролога.
ЦЕЛЬ - предикат, который надо согласовать с базой данных (с базой фактов и правил).
Раздел целей, начинающийся ключевым словом GOAL, является необязательным. Если он отсутствует, программа будет работать только под управлением системы (т.е. нельзя будет создать EXE - файл), при этом цель будет запрашиваться в диалоговом окне в виде "Goal:" и Турбо-Пролог будет ожидать до тех пор, пока цель не будет введена. Целью может являться любой предикат Пролог-программы или их последовательность, разделяемая запятыми. В последнем случае сложная цель согласуется, если согласуются все ее составляющие подцели.
ПОДЦЕЛЬ - предикат, который необходимо согласовать с базой данных, чтобы выполнить согласование предиката-цели, который определен через рассматриваемый; т. е. предикат который на определенном шаге работы программы сам становится целевым.
Типы данных или предопределенные объекты
(PREDEFINED DOMAINS)
В Турбо-Прологе имеется 5 стандартных типов доменов и служебные типы доменов.
1.2.1 Стандартные типы данных
char - символ (размер 1 байт)
integer - целое число (размер 2 байта)
real - действительное число (размер 8 байт)
string - последовательность символов типа char, которая заключена в кавычки
symbol - последовательность букв латинского алфавита, цифр и знаков подчеркивания, которая начинается со строчной буквы или заключена в кавычки.
CHAR - это 8-битовый код знаков ASCII, заключенный в апостофы, например 'А' или '*'. Можно использовать цифровое значение кода ASCII в виде '\13' или условные обозначения '\n' (символ новой строки), '\t' (символ табуляции).
INTEGER - определяет домен целых чисел в диапазоне [-32768,+32767].
REAL - определяет домен вещественных чисел: (+/-) [1Е-30,1Е+30]. В общепринятом для языков программирования формате, например: 0.9Е2, -56.89, и т.п. Целые числа при необходимости автоматически преобразуются в вещественную форму.
STRING - это последовательность символов, заключенная в кавычки, например "resultat" или "получили w= ". В строках можно использовать цифровые и условные обозначения кодов ASCII:
" \n \t Имя автора - ".
SYMBOL - определяет домен символьного типа, сюда относятся
все имена, начинающиеся с малой буквы, а также строки. Данные типа symbol в отличие от данных типа string запоминаются в таблице символов. Таблица символов размещается в оперативной памяти, поэтому ее использование обеспечивает наиболее быстрый поиск. Однако для построения таблицы символов требуется дополнительное время.
1.2.2 Дополнительные типы данных
ref - ссылочный номер базы данных
dbasedom - определяет объект в терме для глобальных баз данных
bt_selector - возвращаемый указатель бинарного дерева
db_selector - определенный пользователем указатель внешней базы данных
place - переменная области размещения, принимает значения:
in_memory - в памяти;
in_ems - в расширенной памяти;
in_file - в файле
file - файловая переменная, принимает значения:
keyboard - клавиатура;
screen - экран;
printer - принтер;
com1; stdin; stdout - стандартные порты ввода/вывода
. - другие значения, присвоенные пользователем
reg - переменная для обращения к регистрам ОЗУ, принимает значение: reg(AX,BX,CX,DX,SI,DI,DS,ES)
bgi_ilist - список целых для предикатов BGI-графики.
Списки
СПИСКИ - это структура данных Турбо-Пролога для формирования составных объектов. Список состоит из элементов (термов), заключенных в квадратные скобки и разделенных запятыми. Список целых чисел представляется как [1,2,3,9,-3,-2]. Он принадлежит к определяемому домену ilist, объявляемому как:
domains ilist = integer *
Если элементы в списке смешанного типа, например, список, содержащий как символы, так и целые числа, он должен быть выражен символами в соответствующем описании:
domains
element = c(char); i(integer)
list = element *
представляет, например, такой список
[i(12), i(34), i(-567), c('x'), c('y'), c('z'), i(987)].
Унификация
УНИФИКАЦИЯ (отождествление) - механизм сопоставления целевого предиката с базой данных и конкретизации (сопоставления)
переменных.
Механизм унификации Турбо-Пролога использует и реализует следующие правила при согласовании целей:
1) Свободные переменные могут быть унифицированы с любым термом.
2) Атомы и константы могут быть унифицированы только сами с собой.
3) Структурный терм может быть унифицирован с другим структурным термом, если оба они имеют одинаковые функторы и равное число компонент, при этом константы, используемые
в качестве компонент могут быть связаны только сами с собой или со свободной переменной.
Пример 1: Два терма data(D,M,1993) и data(D1,"май",Y) - сопоставимы. Результатом их унификации (сопоставления) является отождествление переменных:
D = D1 M = "май" Y = 1993
Пример 2: Два терма data(D,M,1993) и data(A,B,1990) - несопоставимы. Не сопоставимы термы data(X,Y,Z) и point(X,Y,Z).
При унификации списков с одной стороны список рассматривают как единый объект, с другой как составной - в виде двух частей. Первую часть списка называют головой (head), а вторую хвостом (trail). Такое представление описывается шаблоном списка, где
заключенные в квадратные скобки элементы головы и хвоста разделяются вертикальной чертой: [H|T]. При этом голова Н - первый элемент списка, хвост Т - список - оставшаяся часть заданного списка.
Пример 3: Для списка L = [a,b,c]. Голова: H=a, хвост: T=[b,c]. То есть L унифицируется с указанным шаблоном [H|T].
Список L может быть сопоставлен со следующими шаблонами:
L = [a,b,c] = [a|[b,c]] = [a,b|[c]] = [a,b,c|[]]
[H|T] [a,H|T] [a,b,H|T] H = a H = b H = c
T = [b,c] T = [c] T = []
где [] - пустой список.
Отсечение
ОТСЕЧЕНИЕ (cut - !) - механизм, который предотвращает возврат (попытку пересогласования предикатов-подцелей, объявляя при этом предикат-цель не согласованным, т. е. как - fail) из тех точек программы, в которых он поставлен.
Причины для включения отсечения в программу:
1. Программа будет выполняться быстрее, т. к. не будет тратиться время на попытки найти новое сопоставление целей, о которых заранее известно, что они не внесут ничего нового в решение.
2. Программа может занимать меньше места в памяти ЭВМ, т. к. отсутствие необходимости запоминать точки возврата для следующего анализа позволяет более экономично использовать память.
+----------------------------------------+
¦ Добавляя отсечение вы повышаете ¦
¦ эффективность своих Пролог-программ. ¦
+----------------------------------------+
Отсечение позволяет пользователю указать системе - какие из сделанных ранее выборов не следует пересматривать при бектрекинге. Например, пусть дано правило в обобщенной форме:
Р :- р1, р2, р3, !, р4, р5, р6.
Турбо-Пролог будет пытаться согласовывать подцели р1,р2,р3, пока истинность р3 не вызовет переход вправо от '!' (для анализа подцели р4). В этот момент значения всех маркеров-указателей, которые использовала система при согласовании р1,р2,р3 "замораживаются" и более изменены быть не могут. Теперь при согласовании следующих подцелей Турбо-Пролог может осуществлять бектрекинг только среди р4,р5,р6. Любая попытка перехода влево от '!' вызовет прекращение процесса согласования всего правила и значение конъюнкции Р объявляется ложным.
Замечание: Пусть Р - правило в котором встречается предикат отсечения. Нужно помнить, что как только правило Р было выбрано в качестве целевого утверждения, выбор Р и всех решений принятых после него становится фиксированным. Это значительно сокращает перебор при поиске решений.
Отсечение используют, как правило, в трех основных случаях.
а). Подтверждение правильности выбора правила.
Этот случай связан с ситуацией, когда программист хочет сообщить системе, что нужное правило для данного целевого утверждения найдено и его не следует менять. По сути - это превращение предиката в детерминированное логическое выражение.
Пример: G:-G1,G2,G3.
G1. G2:-!.
Если предикат G3 не согласуется, то при выполнении бектрекинга, будет пересогласовываться с базой данных только подцель G1, т.к. подцель G2-детерминирована.
Недетерминироваными являются предикаты, которые могут вызываться на пересогласование с базой данных при бектрекинге (возв
рате по несогласованию следующего предиката). Детерминированные предикаты при возврате пропускаются (не пересогласовываются с базой данных).
б). Проверка на согласование подцелей (отмена бектрекинга).
Пример: G:-G1,!,G2,G3.
G:-G4,G5.
Если цель G2 не согласуется с базой данных, то объявить цель
G неудачно согласованной в целом без повторного согласования G1
при возврате по бектрекингу. При этом не происходит даже перехода на вторую ветвь определения цели G.
в). Использование комбинации "отсечение - fail".
Fail - это встроенный предикат, выполнение которого всегда заканчивается неудачей, т.е. его можно рассматривать, как команду включить механизм бектрекинга и использовать для организации циклов. Появление отсечения непосредственно перед fail изменит нормальное выполнение обратного поиска.
Пример: G:-G1,G2,G3,!,fail.
В любом случае цель G никогда не будет согласована с базой данных и всегда будет принимать значение "ложно".
Рекурсия
РЕКУРСИЯ - механизм, который позволяет перевызывать на согласование с базой данных предикат, который в качестве предиката-подцели ссылается на самого себя.
Обычная стратегия решения задач состоит в том, чтобы разбить исходную задачу на более мелкие подзадачи, решить их, а затем объединить подзадачи с тем, чтобы получить решение исходной задачи. Может потребоваться разбиение подзадачи на еще более мелкие и решение их по частям.
Если подзадача есть уменьшенный вариант исходной задачи, то способ ее разбиения и решения идентичен примененному в исходной задаче.
Такой процесс называется рекурсией. Для того чтобы описанный метод решения был результативным, он должен в конце концов приводить к задаче, решаемой непосредственно. Решить ее позволяют утверждения, называемые граничными условиями.
Механизм рекурсии - один из наиболее традиционных механизмов программирования.
+------------------------------------------------------+
¦ Турбо-Пролог - это последовательный язык. ¦
¦ Несмотря на то, что он вышел из математической ¦
¦ логики, он последовательно сопоставляет с базой ¦
¦ данных предикаты (или выражения для одного ¦
¦ предиката) в порядке их нахождения в теле ¦
¦ программы. ¦
+------------------------------------------------------+
Для увеличения производительности программ и экономии стека следует применять остаточную рекурсию (или итерационное определение предиката).
Пример 1: Вычисление факториала методом рекурсии. PREDICATES
factorial(INTEGER,INTEGER) factorial_it(INTEGER,INTEGER,INTEGER) CLAUSES
factorial(1,1):-!. factorial(N,X):- M = N-1, factorial(M,Y), X = Y*N.
Пример 2: Вычисление факториала с помощью остаточной рекурсии (итерационное вычисление). PREDICATES factorial(INTEGER,INTEGER)
factorial_it(INTEGER,INTEGER,INTEGER)
CLAUSES
factorial(N,X):-factorial_it(N,1,X),!. factorial_it(N,X,C):not(N=1), M = N-1, Y = X*N,!,
factorial_it(M,Y,C). factorial_it(_,X,X):-!.
Бектрекинг
БЕКТРЕКИНГ - механизм возврата, который работает следующим образом: если не произошло согласование текущего предиката-цели с
базой данных (т. е. механизм унификации сработал как fail), то происходит вызов на согласование с базой данных предиката, который до этого выступал как целевой. Если предикат был объявлен несколько раз, то осуществляется переход к следующему (по порядку записи) определению этого предиката.
Сложное целевое выражение вида: GOAL G:-G1,G2,.,GN. обрабатывается слева направо, а соответствующие выражения для этих предикатов-подцелей Gi при этом просматриваются сверху вниз.
При этом Турбо-Пролог поочередно пытается согласовать каждую подцель. Если обнаружен факт который сопоставим с i-ой подцелью, то Турбо-Пролог ставит в этом месте программы i-ый маркер, при
этом некоторые свободные переменные могут быть конкретизированы. Если некоторая свободная переменная X - конкретизируется, то конкретизируются и все ее вхождения в последующие подцели.
Далее Турбо-Пролог пытается согласовать i+1-ую подцель. Для каждой новой подцели просмотр описаний предикатов начинается заново. Если согласование всех подцелей закончилось успехом, система выдает полученное решение.
В противном случае, каждый раз, когда целевое утверждение не выполняется (в программе нет фактов сопоставимых с целью), ТурбоПролог запускает механизм обратного поиска -"бeктрекинг", т.е. возвращается на шаг назад и пытается найти новое согласование для
(i-1)-ой подцели, начиная поиск с помеченного (i-1)-ым маркером определения предиката. При этом все конкретизированные ранее (при предыдущем согласовании (i-1)-ой подцели) переменные вновь становятся свободными.
Может случится, что в процессе поиска решения Турбо-Пролог будет вынужден все время сдвигаться влево по целевому выражению
и, наконец, исчерпает свои возможности: попытается выйти за левую границу целевого утверждения. Это означает, что данная задача не имеет решений ( нет фактов удовлетворяющих цели) и система ответит: No solution. (Решения нет).
Большинство функций, которые организованы в виде циклически замкнутых процедур (циклов), можно описать, или с использованием механизма рекурсии, или с использованием механизма возврата (бектрекинга). Например, программа заполнении окна, размером во
весь экран, символом '_' может иметь два варианта:
Пример 1: (Рекурсивное выполнение функции заполнения окна символом '_').
PREDICATES ful(INTEGER,INTEGER,INTEGER) ful1(INTEGER,INTEGER,INTEGER)
CLAUSES
ful(C,_,C):-!.
ful(C,R,F):-C1=C+1,ful1(0,R,C),ful(C1,R,F),!.
ful1(R,R,_):-!.
ful1(R,F,C):-R1=R-1,scr_char(R,C,'_'),ful1(R1,F,C),!.
GOAL makewindow(1,31,0,"",0,0,25,80), ful(0,25,80),readchar(_),removewindow,!.
Пример 2: (Выполнение функции заполнения м '_' может иметь два варианта:
Пример 1: (Рекурсивное выполнение функции заполнения окна символом '_').
PREDICATEторая содержит один детерминированный предикат). DATABASE - CURRENT determ color(INTEGER,INTEGER) PREDICATES repeat
CLAUSES repeat. repeat:-repeat.
GOAL makewindow(1,31,0,"",0,0,25,80), assert(color(0,0)),repeat,color(R,C),scr_char(R,C,'_'), R1=R+1,retractall(color(_,_)),assert(color(R1,C)), R=24, C1=C+1,retractall(color(_,_)),assert(color(0,C1)),C1=80, retractall(color(_,_)),readchar(_),removewindow,!.
Пример демонстрирует, что необходимо знать правила выбора вида реализации пролог-программы, то есть когда необходимо воспользоваться рекурсией, а когда бектрекингом.
+------------------------------------------------------+
¦ Если вы описываете процедуру, которая имеет ¦
¦ замкнутый цикл с небольшим количеством шагов, то ¦
¦ используйте механизм рекурсии. ¦
+------------------------------------------------------+
Рекурсия - идеальный механизм для обработки списковых структур данных. Но помните о том, что при каждом шаге рекурсия отнимает кусочек памяти в ОЗУ, организуя стек для сохранения текущих параметров этого механизма.
+------------------------------------------------------+
¦ Если вы описываете процедуру, которая будет ¦
¦ организована как бесконечный цикл или цикл с ¦
¦ большим количеством шагов (количество которых вы ¦
¦ не можете определить заранее), то используйте ¦
¦ встроенный механизм возврата (бектрекинг). ¦
+------------------------------------------------------+
Например, если вы создаете систему диалогового интерфейса,
то описывая все функции перемещения в диалоговых окнах (количество перемещений не может быть ограничено) необходимо использовать механизм бектрекинга.
Рассмотрим задачу, для решения которой нужна организация бесконечного цикла, что не возможно осуществить с помощью рекурсии ( т. к. это приведет к переполнению стека ).
Задача:
В графическом режиме на синем фоне в центре экрана голубыми буквами должна появиться надпись:
Дмитрий Белов
Россия
Далее, фон по точкам перекрашивается из синего цвета в розовый, а буквы надписи из голубого цвета в белый. Выполнение программы должно прерываться нажатием клавиши Esc.
Программа:
bgidriver "_CGA_driver_far"
PREDICATES
ranpick convers(integer,integer,integer) repeat
CLAUSES
repeat.
repeat:- not(keypressed), repeat.
ranpick:-repeat,random(320,X),random(200,Y), getpixel(X,Y,C),convers(X,Y,C),fail.
ranpick:-!.
convers(X,Y,1):-putpixel(X,Y,3),!. convers(X,Y,0):-putpixel(X,Y,2),!.
GOAL
DetectGraph(D,M),InitGraph(1,1, _, _, "\\"), SetBkColor(1),SetColor(1), settextstyle(0,0,3),outtextxy(5,50,"Дмитрий Белов"), settextstyle(0,0,1),outtextxy(100,100,"Россия"), ranpick,closegraph(),exit(0),!.