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

Материал из 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 обработкаФайла

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

Проперти (секция properties) так же могут реализовываться через клаузы, и тогда они водят неявное описание предиката(ов). Если есть (i) проперти, то клауза должна соответствовать предикату properyName : (propertyValue), а для (o) - properyName : () -> propertyValue.

interface обработкаФайла
properties
  размерФайла : unsigned(0).
end interface обработкаФайла
 
implement обработкаФайла
clauses
  размерФайла() = Размер :-
    Размер64 = fileSystem_api::getFileSize(handle_fv),
    unsigned64(Размер, _).
 
end implement обработкаФайла