Инструменты пользователя

Инструменты сайта


examination:flp:question52

Содержание

disk

Предикат disk используется для изменения текущего диска и/или каталога/подкаталога и имеет формат:

 disk(Path) %(i),(о)

При вызове со свободной переменной в качестве параметра, disk возвратит текущий каталог. В DOS-ориентированных версиях для переключения на другой диск без изменения существующего текущего каталога на этом диске используйте D:. Здесь D - буква, обозначающая устройство.

dot

Основными предикатами, используемыми в графике, являются предикат dot (точка) и line (линия).

Вызов предиката dot(Row,Column,Color) приводит к размещению точки в месте, определяемом значениями Row (Строка) и Column (Столбец). Первые два параметра - это целые значения в диапазоне от 0 до 31999.

div

Функция div вычисляет целое частное от деления X ни Y (где X и Y - целые).

 X div Y % (i,i)

Выражение Z=X div Y ставит в соответствие Z целую часть результата. Например:

 Z=7 div 4  %Z будет равно 1
 Y=4 div 7  % Y будет равно 0

domains

Раздел domains служит двум полезным целям. Во-первых, вы можете задать доменам осмысленные имена, даже если внутренне эти домены аналогичны уже имеющимся стандартным. Во-вторых, объявление специальных доменов используется для описания структур данных, отсутствующих в стандартных доменах. Иногда очень полезно описать новый домен - особенно, когда вы хотите прояснить отдельные части раздела predicates. Объявление собственных доменов, благодаря присваиванию осмысленных имен типам аргументов, помогает документировать описываемые вами предикаты.

Рассмотрим несколько примеров.

1. Данный пример показывает, как объявление доменов помогает документировать предикаты:

   Франк - мужчина, которому 45 лет. 

Используя стандартные домены, вы можете так объявить соответствующий предикат:

person(symbol,symbol,integer).

В большинстве случаев такое объявление будет работать очень хорошо. Однако предположим, что несколько месяцев спустя после написания программы, вы решили скорректировать ее. Есть опасение, что подобное объявление этого предиката абсолютно ничего вам не скажет. И напротив, декларация этого же предиката, представленная ниже, поможет вам разобраться в том, что же представляют собой аргументы данного предиката:

 domains
    names,sex=symbol
    age=integer
 predicates
    person (name,sex,age)

Одним из главных преимуществ объявления собственных доменов является то,что Пролог может отслеживать ошибки типов, например, такие:

 same_sex(Х,Y):-
    person(X,Sex,_),
    person(Sex,Y,_).

Несмотря на то, что и name и sex описываются как symbol, они не эквивалентны друг другу. Это и позволяет Прологу определить ошибку, если вы перепутаете их. Это полезно в тех случаях, когда ваши программы очень велики и сложны.

Почему же мы не можем использовать специальные домены для объявления всех аргументов, если они привносят больше смысла в обозначение аргументов? Ответ заключается в том, что аргументы с типами из специальных доменов не могут смешиваться между собой, даже если эти домены одинаковы. Именно поэтому, несмотря на то, что name и sex принадлежат одному домену symbol, они не могут смешиваться. Однако все собственные домены пользователя могут быть сопоставлены стандартным доменам.

2. Следующий пример программы pro21_1.pro при его загрузке приведет к ошибке типа.

 domains
    product,sum = integer
 predicates
    add_em_up(sum,sum,sum)
    multiply_em(product,product,product)
 clauses
    add_em_up(X,Y,Sum):-
       Sum=X+Y.
    multiply_em(X,Y,Product):-
       Product=X*Y.

Текст этой программы можно взять здесь.

Эта программа выполняет две операции: складывает и умножает. Зададим ей следующую цель:

 add_em_up(32,54,Sum).

Пролог ответит:

 sum=86
 1 Решение

что является суммой двух целых чисел, которые вы передали в программу. С другой стороны, эта же программа с помощью предиката multiply_em умножает два аргумента. Поэкспериментируем. Если вам нужно узнать произведение чисел 13 и 31, введите цель:

 multiply_em(31,13,Product).

Пролог вернет вам корректный результат:

 Product=403	
 1 Решение

Предположим, что вам понадобилась сумма чисел 42 и 17; цель выглядит так:

 add_em_up(42,17,Sum).

А теперь, допустим, вы хотите удвоить произведение 31 на 17. Задаете следующую цель:

 multiply_em(31,17,Sum),
 add_em_up(Sum,Sum,Answer)

и ждете, что Пролог ответит:

 Sum=527,
 Answer=1054	
 1  Решение

Однако вместо этого вы получите ошибку типа. Это случилось из-за того, что имела место попытка передать результирующее значение предиката multiply_em, которое относится к домену product, в качестве первого и второго аргументов (которые должны относится к домену sum) в предикат add_em_up. Это, собственно, и привело к ошибке, т.к. домен product отличается от домена sum. И хотя оба эти домена соответствуют типу integer - это различные домены.

Поэтому, если переменная в предложении используется более чем в одном предикате, она должна быть одинаково объявлена в каждом из них. Очень важно, чтобы вы поняли концепцию описанной здесь ошибки типа, что позволит избегать сообщений об ошибках компиляции. Различные автоматические и явные преобразования типов, предлагаемые Прологом, будут описаны ниже.

display

Существует еще один предикат, который выполняет те же действия, что и write, за тем исключением, что он игнорирует все сделанные объявления операторов. Этот предикат называется display. Различие между write и display иллюстрирует следующий пример:

?— write(a+b*c*c),nl,display(a+b*c*c),a+b*c*c+(a,*(*(b,c),c)) да

Обратим внимание на то, что предикат display обработал атомы + и * — точно так же, как и любые другие атомы, которые он печатает в этом терме. Как правило, нежелательно, чтобы печатаемые структуры выглядели подобным образом, так как наличие операторов обычно делает более понятными при чтении как вводимые, так и выводимые программой данные. Однако иногда, когда мы не совсем уверены в том, что знаем, каков приоритет операторов, использование предиката display может оказаться очень полезным.

examination/flp/question52.txt · Последние изменения: 2014/01/15 12:17 (внешнее изменение)