Где декларируются предикаты?
Обычно, говоря о 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 обработкаФайла