Где декларируются предикаты?
Обычно, говоря о 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 class обработкаФайла class обработкаФайла : обработкаФайла end class обработкаФайла implement обработкаФайла выделитьИзФайлаОтрезокТекстаСЗаданнойДлиной(ИмяФайла,ЧислоСимоволов)=ОтрезокТекста:- ПолныйТекстФайла=прочитатьФайл(ИмяФайла), ... end implement обработкаФайла
Обратите внимание, декларация класса (class... end class) не содержит ничего, кроме указателя на используемый интерфейс. Но, несмотря на это, ее нельзя исключить из кода и связать имплементацию с интерфесом каким-либо другим способом.
Приведенный фрагмент кода мог бы выглядеть и по-другому (использование другого имени интерфейса)
interface fileHandling predicates выделитьИзФайлаОтрезокТекстаСЗаданнойДлиной:(string ИмяФайла, unsigned ЧислоСимоволов) ->string end class fileHandling class обработкаФайла : fileHandling end class обработкаФайла implement обработкаФайла выделитьИзФайлаОтрезокТекстаСЗаданнойДлиной(ИмяФайла,ЧислоСимоволов)=ОтрезокТекста:- ПолныйТекстФайла=прочитатьФайл(ИмяФайла), ... end implement обработкаФайла
Все три приведенные способа декларирования предикатов определяют различные свойства и приемы их использования в классах и объектах и поэтому не являются равнозначными альтернативами.