Где декларируются предикаты?

Материал из wikiru.visual-prolog.com

Обычно, говоря о Visual Prolog, подчеркивают, что это - типизированный язык. Это подразумевает, что существует объявление (или декларация) типов данных, используемых в предикатах в качестве входных или выходных параметров, а также других характеристик предикатов. Это объявление используется затем в клаузе - исполняемой части предиката, где и интерпретируется как программистом, так и компилятором.

Например, в следущем коде

predicates
  выделитьИзФайлаОтрезокТекстаСЗаданнойДлиной:(string ИмяФайла, unsigned ЧислоСимоволов) ->string
clauses
  выделитьИзФайлаОтрезокТекстаСЗаданнойДлиной(ИмяФайла,ЧислоСимоволов)=ОтрезокТекста:-
    ПолныйТекстФайла=прочитатьФайл(ИмяФайла),
    ...

декларация (раздел predicates) и клауза (раздел clauses) помещаются рядом по тексту. Но это лишь частный случай возможного их взаимного размещения. Местом размещения исполняемой части всегда является имплементация класса (implement ... end implement).

Местами помещения декларации могут быть:

  • та же имплементация класса (implement ... end implement)
  • декларация одноименного класса (class ... end class)
  • декларация интерфейса, который квалифицирет одноименный класс (interface ... end interface)

В первом случае декларация может размещаться как выше, так и ниже по тексту.

Хорошим стилем считается, когда декларация помещена непосредственно над клаузой, как в примере выше. При этом имена разделов по-прежнему пишутся во множественном числе (predicates, clauses).

Во втором случае декларация предиката и его клауза связаны однозначно, поскольку однозначно общим именем связаны декларация класса и его имплементация.

class обработкаФайла
predicates
  выделитьИзФайлаОтрезокТекстаСЗаданнойДлиной:(string ИмяФайла, unsigned ЧислоСимоволов) ->string
end class обработкаФайла
 
implement обработкаФайла
  выделитьИзФайлаОтрезокТекстаСЗаданнойДлиной(ИмяФайла,ЧислоСимоволов)=ОтрезокТекста:-
    ПолныйТекстФайла=прочитатьФайл(ИмяФайла),
    ...
end implement обработкаФайла

Следует подчеркнуть, что декларация класса - это сущность, неотделимая от имплементации класса с тем же именем. То есть нельзя в какую-либо произвольную декларацию класса поместить декларацию предиката, а в какую-то имплементацию класса с другим именем поместить клаузу и попытаться их связать какими-то ссылками, использующими эти имена. Имя класса однозначно определяет его декларацию и его имплементацию. Именно в них можно поместить декларацию предиката и его клаузу.

Третий способ декларирования предиката связан с порождением объектов, поскольку классы, имеющие интерфейс, могут быть использованы только как генераторы объектов. Имя интерфейса в этом случае может не совпадать с именем класса и, соответственно, имплементации.

Наш фрагмент кода будет выглядеть в этом случае иначе.

interface обработкаФайла
predicates
  выделитьИзФайлаОтрезокТекстаСЗаданнойДлиной:(string ИмяФайла, unsigned ЧислоСимоволов) ->string
end interface обработкаФайла
 
class обработкаФайла : обработкаФайла
end class обработкаФайла
 
implement обработкаФайла
  выделитьИзФайлаОтрезокТекстаСЗаданнойДлиной(ИмяФайла,ЧислоСимоволов)=ОтрезокТекста:-
    ПолныйТекстФайла=прочитатьФайл(ИмяФайла),
    ...
end implement обработкаФайла

Обратите внимание, декларация класса (class... end class) не содержит ничего, кроме указателя на используемый интерфейс. Но, несмотря на это, ее нельзя исключить из кода и связать имплементацию с интерфесом каким-либо другим способом.

Приведенный фрагмент кода мог бы выглядеть и по-другому (использование другого имени интерфейса)

interface fileHandling
predicates
  выделитьИзФайлаОтрезокТекстаСЗаданнойДлиной:(string ИмяФайла, unsigned ЧислоСимоволов) ->string
end interface fileHandling
 
class обработкаФайла : fileHandling
end class обработкаФайла
 
implement обработкаФайла
  выделитьИзФайлаОтрезокТекстаСЗаданнойДлиной(ИмяФайла,ЧислоСимоволов)=ОтрезокТекста:-
    ПолныйТекстФайла=прочитатьФайл(ИмяФайла),
    ...
end implement обработкаФайла

Все три приведенные способа декларирования предикатов определяют различные свойства и приемы их использования в классах и объектах и поэтому не являются равнозначными альтернативами.