В языке Visual Prolog используются следующие разделы программы:
(class) facts – объявление предикатов, описывающих факты (а также внутренних баз данных и фактов-переменных);
(class) predicates – объявление предикатов (служит для описания используемых программой предикатов, этот раздел является обязательным);
domains – определение типов данных (содержит определения доменов, которые описывают различные типы объектов, используемых в программе, если используются стандартные типы, то раздел может не использоваться);
constants – объявление констант;
clauses – определение фактов или правил (в раздел заносятся факты и правила статической базы данных, которая и является собственно программой, этот раздел является обязательным);
goal – цель программы (в разделе формулируется цель (запрос) созданной программы. Составными частями при этом могут являться некие подцели, из которых формируется единая цель программы, этот раздел является обязательным и может быть только один в проекте в файле main.pro).

Для примера рассмотрим следующий код программы:

implement main
	open core, console 

domains
	gender = female(); male().

class facts – familyDB
	person : (string Name, gender Gender).
	parent : (string Person, string Parent).

class predicates
	father : (string Person, string Father) nondeterm anyflow. % Отец
	grandFather : (string Person, string GrandFather) nondeterm (o,o). % Дед
	ancestor : (string Person, string Ancestor) nondeterm (i,o). % Предок

clauses
	father(Person, Father) :- parent(Person, Father), person(Father, male()).

	grandFather(Person, GrandFather) :- parent(Person, Parent), father(Parent, GrandFather).

	ancestor(Person, Ancestor) :- parent(Person, Ancestor).
	ancestor(Person, Ancestor) :- parent(Person, P1), ancestor(P1, Ancestor).

	person("Bill", male()).
	person("John", male()).
	person("Pam", female()).
	parent("John", "Judith").
	parent("Bill", "John").
	parent("Pam", "Bill").

	run() :->
		init(),
		write("father; test"),nl,
		father(X, Y),
		write(Y, "is the father of", X),nl,
		fail.
	run() :-
		nl,
		write("grandFather test"),nl,
		grandFather(X, Y),
		write(Y, "is the GrandFather of", X),nl,
		fail.

	run() :-
		nl,
		write("ancestor of Pam test"),nl,
		X = "Pam",
		ancestor(X, Y),
		write(Y, "is the ancestor of", X),nl,
		fail.

	run() :-
		nl,
		write("End of test"),
		_=readLine().

end implement main

goal
	console::run(main::run).
В данном примере используются почти все основные разделы программы.
Язык Visual Prolog – типизированный, поэтому предикаты необходимо объявлять. В объявлении предиката указывается его имя, ставится знак двоеточия, а затем в круглых скобках через запятую перечисляются имена доменов (типов данных) аргументов:
class facts – familyDB
	person : (string Name, gender Gender).
Словом familyDB обозначено имя базы данных. В объявлениях предикатов можно использовать комментарии специального вида. Слова Name и Gender в этом объявлении обозначают комментарии. Компилятор их игнорирует. Такие комментарии пишутся в одно слово с прописной буквы.

Предикаты объявляются в разделах class facts (если определяются только в виде фактов) или class predicates, а определяются в разделе clauses. Цель программы формулируется в разделе goal, который находится в файле main.pro. Обычно в разделе goal только вызывается некоторый предикат, который используется для составления запросов. В данном примере и всюду далее таким предикатом является run.
Раздел open имплементации класса main следует изменить следующим образом (см. урок 1):

open core, console
Вывод решений для запроса, например для цели ?- father(X, Y), организуется с помощью предиката fail. Этот предикат имеет значение ложь. Он вынуждает программу вернуться для поиска других решений.

Ключевое слово nondeterm в объявлении предиката означает, что область истинности этого предиката может содержать более одного элемента или не содержать ни одного. Ключевое слово anyflow означает, что некоторые аргументы предиката могут быть как входными, так и выходными. Последовательность (i,o) – означает, что первый аргумент предиката входной, а второй – выходной, ну и последовательность (o,o) – соответственно означает, что оба аргумента предиката – выходные, они возвращают некоторые значения.

Предикат init инициализирует консоль.

Для ввода и вывода в консоли используются буфер ввода и буфер вывода, соответственно. Предикат clearInput очищает буфер ввода, предикат clearOutput очищает буфер вывода. Предикат readLine считывает содержимое буфера ввода в строку (string) и при этом полностью очищает содержимое этого буфера. В данном случае программа просто ожидает ввода любого символа.

                                                                       << предыдущий | следующий >>


2016-06-04 • Просмотров [ 406 ]