Скачиваний:
41
Добавлен:
22.05.2015
Размер:
144.38 Кб
Скачать

Двенадцать месяцев

Задание 12. Объявить недетерминированный предикат: месяц(string Имя_Месяца,

unsigned Номер_по_порядку,

unsigned Количество_дней).

Определить в программе все 12 месяцев года. Вывести на экран в одну строку через пробел имена всех чётных месяцев и их продолжительность.

Задание 13. Вывести имена месяцев, продолжительностью 31 день.

Задание 14. Вывести имена месяцев, имя которых содержит не менее пяти символов. Подсказка: для определения длины строки воспользуйтесь предикатом: string::length/1.

Задание 15. Вывести суммарную продолжительность летних месяцев.

Задание 16. Вывести номера тех месяцев, которые заканчиваются на мягкий знак. Подсказка: для определения наличия мягкого знака в конце строки воспользуйтесь предикатом string::hasSuffix/3 или string::lastChar/3 (на Ваше усмотрение).

Задание 17. Вывести имена месяцев, в имени которых есть буква ‘р’. Подсказка: для определения наличия этой буквы воспользуйтесь предикатомstring::searchChar/2.

Зелёные и красные отсечения

Завершая рассмотрение механизма поиска с возвратом, следует иметь в виду, что использовать отсечения и, тем более, удалять их надо осмотрительно. Если Вы неосмотрительно поставили отсечение там, где оно не нужно, то самым худшим результатом работы Вашей программы будет потеря решений, которые Вы отсекли. Если же Вы не поставите отсечение там, где оно на самом деле должно быть, то результатом будет получение неправильных решений, что гораздо хуже, чем пропуск решений.

Рассмотрим простой пример определения максимального числа из двух чисел, введённых с клавиатуры.

Пример 10. В нижеприведённой программе используется два явно описанных условия: для случая, когда первое число больше второго и когда первое число меньше или равно второму.

run():-

  init(),

  X=read(),Y=read(), % ввод двух чисел

  clearInput(), % очистка буфера ввода

   (

    X>Y,!,write("Максимальное число: ",X); % для X>Y

    X<=Y,write("Максимальное число: ",Y) % для X<=Y

   ),

  _=readchar(),!;

  write("\nПрограмма завершена"),

  _=readchar().

Рассмотрим более пристально фрагмент:

X>Y,!,write("Максимальное число: ",X);

X<=Y,write("Максимальное число: ",Y)

В данном фрагменте после явной проверки условия X>Y стоит отсечение. Зачем оно нужно? По большому счёту его можно и убрать. Этим мы не нарушим правильность программы. Это отсечение нужно только для того, чтобы указать Прологу, что если условие X>Y истинно, то случай X<=Y рассматривать не надо и, следовательно, его можно отсечь.

Отсечение, удаление которого не изменяет правильность программы, называется зелёным. Зелёные отсечения используют для того, чтобы оптимизировать программу по скорости выполнения за счёт того, что не производятся ненужные откаты назад и лишние проверки условий.

Рассмотрим, как можно оптимизировать программу из примера 10 по размеру. В этой программе условие X<=Y можно удалить, ибо если условие X>Y ложно, то обратное ему условие X<=Y априорно истинно и вычислять его не надо.

Пример 11. В следующей программе используется одно явно описанное условие X>Y с обязательным отсечением. Второе условие X<=Y отсутствует.

run():-

  init(),

  X=read(),Y=read(), % ввод двух чисел

  clearInput(), % очистка буфера ввода

   (

    X>Y,!,write("Максимальное число: ",X); % для X>Y

    write("Максимальное число: ",Y) % для X<=Y

   ),

  _=readchar(),!;

  write("\nПрограмма завершена"),

  _=readchar().

Рассмотрим фрагмент:

X>Y,!,write("Максимальное число: ",X);

write("Максимальное число: ",Y)

В данном фрагменте после явной проверки условия X>Y стоит обязательное отсечение. Почему оно является обязательным? Дело в том, что если запустить эту программу без этого отсечения и ввести данные, соответствующие условию X>Y, то первый ответ этой программы будет правильным. Однако при возможном откате назад отсутствующее условие X<=Y проверяться не будет, и Пролог вернёт неверное решение.

Отсечение, удаление которого изменяет правильность программы, называется красным. Красные отсечения используют для того, чтобы оптимизировать программу по размеру исполнимого кода за счёт того, что из исходного кода удаляются все предикаты, которые можно не выполнять, так как их истинность известна априорно.

Для демонстрации вышеописанных рассуждений запустите цель без рассматриваемого отсечения, в которой использован принудительный откат назад:

run():-

  init(),

  X=read(),Y=read(),

  clearInput(),

   (

    X>Y,write("Максимальное число: ",X);

    write("Максимальное число: ",Y)

   ),

  _=readchar(),

  fail;

  write("\nПрограмма завершена"),

  _=readchar().

Если первым ввести большее число, а вторым – меньшее, то Visual Prolog вернёт Вам два решения: одно правильное, а второе неправильное.

Задание 18. Написать цель для определения того, содержит ли введенная с клавиатуры строка только строчные буквы. Использовать зелёное отсечение. Подсказка: предикаты, определяющие регистр символов string::isLowerCase(string) и string::isUpperCase(string). Указанные предикаты истинны, если соответствующее названию предиката условие истинно. В противном случае они ложны.

Задание 19. Написать цель для определения того, содержит ли введенная с клавиатуры строка только строчные буквы. Использовать красное отсечение.

Задание 20. Написать цель для определения одного из трёх вариантов, содержит ли введенная с клавиатуры строка одни лишь буквы, одни лишь десятичные цифры, или она содержит произвольные символы. Подсказка: воспользуйтесь предикатами string::hasAlpha(string) и string::hasDecimalDigits(string). Указанные предикаты истинны, если соответствующее названию предиката условие истинно. В противном случае они ложны.

Соседние файлы в папке Лабораторные работы