стиль програмування

Тут пропонуються рекомендації по стилю програмування на Visual Prolog, вироблені в компанії Prolog Development Center (PDC).

Ці рекомендації стосуються до новостворюваних кодами. При цьому PDC не планує доведення вже існуючих кодів до відповідності з цими рекомендаціями. Тому коди, поширювані з системою програмування Visual Prolog можуть не відповідати цим стандартам.

загальні рекомендації

  • Клауз предикатів повинні займати, як правило, менше 20 рядків. Тому необхідно передбачати додаткові предикати для організації підпрограм. Ситуації, де предикат може займати більше 20 рядків, відносяться до таких випадків, як, наприклад, 50 властивостей повинні бути встановлені для одного і того ж об'єкта шляхом звернень до нього.
  • Використовуйте повністю певні імена (тобто someClass :: method), - це завжди суміш може призвести програму більш зрозумілою.
  • Методи класу повинні мати значущі імена, читаються спільно з ім'ям класу. Уникайте повторення імені класу в імені методу, тобто ім'я повинно бути:
  • Предикат повинен виконувати точно одну задачу. Тому, якщо у Вас є предикат, який щось робить з кожним елементом списку, розгляньте можливість розбиття його на два предиката: один робить прохід по списку, а другий виконує операцію над елементом. Достроінство такого підходу полягає в тому, що предикат стає простіше (і, отже, простіше для модифікації і розуміння).
  • У загальному випадку, якщо з одного боку від знака рівності ( "=") повинна бути змінна, то розміщуйте її справа. якщо вона пов'язана.

булеві значення

Булеві значення слід використовувати, якщо щось або истино, або хибно. Не слід використовувати такі значення для встановлення відмінностей випадків, таких як зліва і справа, чи горизонтально і вертикально. У таких випадках краще використовувати Спеціалізоване домени.

Відсікання (Cut)

Відсікання (тобто) є предикат, який відсікає (cuts) недетермінізм, тобто відсікає можливість вироблення подальших рішень (відповідно до свого імені).

Відсікається недетермінізм можна розбити на два групи (хоча в ряді випадків відсікання можуть належати обом):

  • Відсікання, які відсікають можливість виконання інших (наступних по порядку) клауз поточного предиката.
  • Відсікання, які ліквідують можливість генерації нових рішень у недетермінірованних викликів предикатів.

Інших значущих причин для використання відсікань немає, крім двох, згаданих вище. Якщо ці цілі зрозумілі, то дуже просто ставити відсікання в правильному місці:

  • або відсікання ставиться в місці, де перебір послідовних клауз більше не потрібно і / або
  • воно ставиться після виклику недетермінірованного (тобто з кваліфікацією nondeterm або multi) предиката, для якого важливо тільки одне рішення.

Перша причина може бути проілюстрована наступним прикладом

У цьому прикладі ми маємо відсікання після перевірки X> 13. Це типовий випадок використання першої причини: "Наші клауз реагують на значення вхідної змінної і відразу (де відразу означає негайно після перевірки X> 13) ми знаходимо правильне рішення".

Зазвичай такого роду відсікання поміщаються відразу після голови клауз або після перевірки, найближчої до голови клауз.

Друга причина може бути проілюстрована на наступному прикладі:

У цьому прикладі відсікання поміщається негайно після недетермінірованного предиката, від якого ми очікуємо єдине рішення.

Вище ми виділили слово негайно двічі, оскільки ключовим словом в розміщенні відсікання є саме слово негайно. вони повинні бути поміщені настільки рано в Клаузе, наскільки це можливо.

Ви повинні з підозрою ставитися до Клаузен, що містить більше одного відсікання. Наявність більше одного відсікання в одному Клаузе часто говорить про наявність помилки в програмі.

Червоні і Зелені відсікання

Взагалі кажучи, ми не заохочуємо зелені відсікання, ми цілком вживаємося з червоними відсіканнями.

Спільнота традиційного Прологу дало визначення червоного і зеленого відсікань. Коротко це: зелене відсікання - це відсікання, яке не змінює семантику предиката, в якому використовується, а червоне відсікання - змінює семантику.

Ясно, що все відсікання, які відсікають всі наступні рішення недетермінірованних предикатів є червоними за своєю природою. Тому відмінності між червоними і зеленими відсіканнями мають сенс тільки для тих відсікань, які запобігають відкати до наступних Клаузен.

У предикате вище відсікання є зеленим (green). оскільки, якщо ми його видалимо, то предикат буде вести себе таким же чином. Коли відсікання мається на першому Клаузе, перевірка X <= 0 во втором клаузе в действительности не нужна (второй клауз соответствует всем остальным случаям, кроме X<0 - прим. Переводчика):

Але без цієї перевірки, однак, відсікання стає червоним, оскільки тепер предикат буде вести себе по-іншому, якщо ми видалимо відсікання (предикат стає недетермінованим, оскільки, навіть якщо X> 0, з'являється ще одне рішення - добре, якщо нешкідливе - прим. перекладача).

Зелені відсікання можуть здатися зайвими, але в дійсності вони використовуються для виключення зайвих варіантів відкату (головним чином по міркуваннями швидкості роботи). В системі Visual Prolog вони можуть, однак, бути необхідними для того, щоб показати компілятору, що деякі предикати є предикатами певного типу, наприклад, процедурами.

Управління з використанням комбінацій вхідних даних

Управління з використанням комбінацій вхідних даних (диспетчеризація) слід використовувати з обережністю. Проблема використання вхідних потоків полягає в тому, що ця проста структура може реагувати на безліч різних ситуацій. Тому коди, які логічно сильно взаємопов'язані, слід розбивати на порівняно незалежні фрагменти, і розташовувати їх послідовно.

При цьому логічно пов'язані коди поміщаються в обробні предикати, розташовані в тому ж класі-модулі, так що диспетчер викликає тільки їх. При цьому сам диспетчер і обробні коди залишаються в безпосередній близькості.

Для такого роду управління рекомендується слідувати правилам:

  • Якщо предикат обробляє багато варіантів вхідних наборів даних, підтримуйте кожен такий варіант простим.
  • Ніколи не створюйте кілька клауз для одного і того ж варіанту вхідних даних, якщо предикат обробляє також "інші" випадки.

Перше правило є правилом прямої дії. Друге правило може бути проілюстровано на наступному прикладі:

Секція clauses вище написана в поганому стилі, оскільки має дві клауз для одного і того ж вхідного набору (17, W, E, R, 13, Y). Це було б не страшно, якби предикат працював би тільки з цим набором. Але тут є клауз і для інших наборів. Ми вважаємо, що такий предикат должет бути переписаний таким чином, щоб кожен клауз предиката qwerty реагував би тільки на спеціальний вхідний набір, залишаючи решту обробку предикатам нижчого рівня:

У цьому коді тепер предикат qwerty містить Клозе, кожен з яких реагує на певну комбінацію вхідних даних. При цьому не суттєво, що для деяких комбінацій вхідних даних використовується єдиний виклик предиката. Головним є те, що Ви не перебирає клауз на одному і тому ж наборі вхідних даних.

Це правило особливо корисно при побудові обробників подій - у Вас не повинно бути більше одного клауз для події "close" (або подібного) в тому ж самому обробнику. Оброблювач подій часто розташовується на кількох сторінках екрану, тому якщо не дотримуватися правила обробки одного виду вхідних наборів одним Клаузен, то Вам необхідно буде переглядати всі клауз обробника, щоб з'ясувати як обрабативется конкретний вхідний набір.

Винятки та обробка помилок

  • Коли відбувається помилка або виняткова ситуація, збудіте виняткову ситуацію за допомогою exception :: raise.
  • Блокуйте (trap) виключення якщо Ви хочете їх обробляти.
  • Використовуйте finally якщо необхідно виконати деякий код навіть при виникненні виключення, і вже потім продовжите виняток.
  • Ознакомьтес з керівництвом по обробці виключень.

Внутрішні та інші помилки

Слід розрізняти внутрішні помилки і помилки, пов'язані з використанням пакета, модуля, класу, компоненти. Якщо порушується внутрішня инвариантность, то це внутрішня помилка. Типовими прикладами внутрішніх помилок є:

  • Факт бази даних, який повинен бути визначений, не визначений насправді.
  • Предикат, який мав би бути процедурою, але компілятор не здатний це розпізнати, перетворений в процедуру шляхом додавання "холостого" клауз. Якщо такий кляуз досягається, то це відбувається від того, що припущення про те, що попередній клауз не може завершитися не успішно, було невірним.

Внутрішні помилки повинні генерувати по одному вилученню на кожну. Використання винятків слід за принципом: по одному на кожну помилку користувача і по одному на кожну внутрішню помилку.

Типові для користувача помилки:

  • Вихід індексу за допустимий діапазон
  • "Неправильний" покажчик на вікно
  • порушення порядку проходження предикатів

Блокування (try / catch) завершення програми може бути передбачена з двох причин:

  • Є бажання обробити виняток. Скажімо, при відкритті файлу виникає переривання, яке повідомить, що файл не існує. В цьому випадку виникає бажання блокувати завершення програми і показати якийсь повідомлення про помилку, яке говорить про те, що файл не існує. Природно, якщо таке виключення не є єдино можливим, то слід продовжити виняток.
  • Є бажання щось зробити незалежно від того, чи переривається виконання предиката. Типовий приклад - Ви що-блокуєте (захоплюєте ресурс), потім щось робите і, нарешті, скидаєте блокування (звільняєте ресурс). Тут Вам треба бути впевненим, що блокування скинута (ресурс звільнений), навіть якщо виконання переривається. З цією метою використовується try / finally.

Типи і потоки введення-виведення

За замовчуванням предикати мають тип procedure (процедури). Не варто писати кваліфікатор procedure до тих пір, поки в цьому не виникне необхідність (але, можливо, в цьому випадку слід розглянути необхідність зміни імені предиката).

За замовчуванням всі аргументи предикатів є вхідними. Невикористані комбінації потоків введення-виведення писати не слід.

Безпосередньо з аргументами можуть бути використані кваліфікатори [in] і [out]. Не пишіть [in]. оскільки аргументи є вхідними за замовчуванням.

Якщо прідікат має тільки один варіант потоків входу-виходу, треба використовувати [out] замість шаблону.

За замовчуванням факти є недетермінованими - nondeterm. Не слід писати nondeterm. якщо в цьому немає особливої ​​необхідності (але слід, можливо, розглянути зміну імені факту).

Схожі статті