Материал: Волченков Логическое программирование язык пролог 2015

Внимание! Если размещение файла нарушает Ваши авторские права, то обязательно сообщите нам

%The Spaniard owns the dog. member(spaniard:H2, N), member(dog:H2, P),

%The Norwegian lives in the first house on the left. member(norwegian:1, N),

%Kools are smoked in the yellow house. member(kools:H3, S), member(yellow:H3, C),

%The man who smokes Chesterfields lives in the house next to

%the man with the fox.

member(chesterfields:H4, S), next(H4, H5), member(fox:H5, P),

%The Norwegian lives next to the blue house. member(norwegian:H6, N), next(H6, H7), member(blue:H7, C),

%The Winston smoker owns snails. member(winston:H8, S), member(snails:H8, P),

%The lucky strike smoker drinks orange juice.

member(lucky_strike:H9, S), member(orange_juice:H9, D), % The Ukrainian drinks tea.

member(ukrainian:H10, N), member(tea:H10, D), % The Japanese smokes parliaments.

member(japanese:H11, N), member(parliaments:H11, S),

%Kools are smoked in the house next to the house where

%the horse is kept.

member(kools:H12, S), next(H12, H13), member(horse:H13, P),

%Coffee is drunk in the green house. member(coffee:H14, D), member(green:H14, C),

%The green house is immediately to the right (your right)

%of the ivory house.

member(green:H15, C), left(H16, H15), member(ivory:H16, C),

%Milk is drunk in the middle house. member(milk:3, D).

%Utility Predicates: permutation([],[]).

permutation([A|X],Y) :- delete(A,Y,Y1), permutation(X,Y1).

151

delete(A,[A|X],X). delete(A,[B|X],[B|Y]) :- delete(A,X,Y). member(A,[A|X]) :- !. member(A1:A2,[B1:B2|X]) :-

atomic(A2), atomic(B2),

( A1 == B1, A2 \== B2 ; A2 == B2, A1 \== B1 ), !, fail.

member(A,[B|X]) :- member(A,X).

next(X,Y) :- left(X,Y). next(X,Y) :- left(Y,X).

left(1,2). left(2,3). left(3,4). left(4,5).

Фотография консоли с результатом работы программы:

| ?- zebra(N). Wait...

water : 1 zebra : 5

[yellow : 1, blue : 2, red : 3, ivory : 4, green : 5] [water : 1, tea : 2, milk : 3, orange_juice : 4, coffee : 5]

[norwegian : 1, ukrainian : 2, englishman : 3, spaniard : 4, japanese : 5]

[kools : 1, chesterfields : 2, winston : 3, lucky_strike : 4, parliaments : 5]

[fox : 1, horse : 2, snails : 3, dog : 4, zebra : 5] N = 1

В заключение данного раздела, два вопроса к аудитории (читателям):

1). С какой целью автор ввёл в код программы Льюиса Бакстера директиву: :- assert(bag(n, 0)). и предикат step_number/1?

Указание: чтобы ответить на этот вопрос, следует вспомнить, с какой целью используется в Прологе глобальная переменная, рассмотренная в лекции 8.

2). Что произойдёт, если после появления последней строки на консоли (N = 1) пользователь попросит систему найти другие ре-

152

шения? А что произойдет, если убрать при этом одно из 14 ограничений в правой части правила для предиката constrains/5?

4.Возможность организации интерфейса Пролога с визуальными языками программирования

Для получения результатов работы программ на Прологе, подобных рассмотренной выше, в более наглядном виде автору уда-

лось реализовать интерфейс Пролога с визуальным языком императивного типа – Visual Basic. В частности, вызывать программу на Прологе из приложения Microsoft Excel 2007 (2010), используя макрокоманду, написанную на языке VBA – диалекте языка Visual

Basic. В результате такого интерфейса получаются результаты, описанные автором в книге [10, с.298 - 302].

Пример программы на Прологе – это проведение так называемых частичных вычислений. В данном случае, автор имеет в виду упрощение символьного выражения, которое может получиться, например, в результате символьного дифференцирования – задачи, которая идеально демонстрирует возможности Пролога как логического языка символьной обработки.

Например, при дифференцировании программой на Прологе

арифметического выражения

ln(a / x) + 5 * x ^ 4 + 4 * x ^ 3 + 3 * x ^ 2 + 2 * x + a

получается следующее выражение:

a * (-1 * x ^ (-1 - 1) * 1) * (a / x) ^ -1 + 5 * (4 * x ^ (4 - 1) * 1) + 4 * (3 * x ^ (3 - 1) * 1) + 3 * (2 * x ^ (2 - 1) * 1) + 2 * 1 + 0.

Такое выражение явно нуждается в упрощении. Один из путей упрощения – частичное вычисление выражения.

Здесь демонстрируется реализация работы программы частичного вычисления на Прологе, которая вызывается из приложения MS Excel (2007, 2010) с помощью макроса, написанного на языке VBA for Excel. Фрагмент листа книги Excel может быть таким, как показано на рис.10.6.

153

Рис. 10.6. Лист книги MS Excel 2010 с результатом работы программы – частичным вычислением арифметического выражения

На рис. 10.7 показана экранная форма, вызываемая, например, щелчком кнопки, установленной непосредственно на листе книги Excel, как показано на рисунке 10.6.

Рис. 10.7. Вызываемая с листа книги MS Excel 2010 пользовательская форма для проведения частичного вычисления

На данной форме установлены командные кнопки, позволяющие (1) загрузить и показать пользователю данного приложения программу на Прологе; (2) ввести и загрузить арифметическое вы-

154

ражение и (3) вызвать и запустить программу на Прологе, упрощающую это выражение (производящую его частичное вычисление).

Отметим, что из текста программы на Прологе, показанного в окне формы на рисунке 10.7, можно увидеть, что исходное (вычисляемое) выражение берётся Прологом из текстового файла string.txt, куда оно было записано после щелчка командной кнопки «Загрузить исходное арифметическое выражение» (процедура-

событие ButtonЗагрузитьИсходноеВыражение_Click на языке

VBA). Результат частичных вычислений, выполненных Прологом, помещается в текстовый файл struct.txt тоже Прологом. Перемещение записей результата из файла struct.txt в правое нижнее поле на форме выполняется снова процедурой на языке VBA.

Интерфейс двух языков программирования в данном примере проявляется в полной мере.

Коды 10.7 – 10.9 представляют тексты программных модулей на языке VBA:

Код 10.7. Модуль макроса частичного вычисления выражения

Public Const IS_ERR_CMUTEX = -1

Public Const IS_ERR_WMUTEX = -2

Public Const IS_ERR_LOCATE = -3

Public Const IS_ERR_CREATE = -4

Public Const IS_ERR_MAPFIL = -5

Public Const IS_ERR_PROLOG = -6

Public Const IS_ERR_WINDOW = -7

Public Declare Function LoadProlog Lib "INT386W" (ByVal _

Command_Renamed As String) As Integer Public Declare Sub HaltProlog Lib "INT386W" (ByVal_

Prolog As Integer)

Public Declare Function InitGoal Lib "INT386W" (ByVal _ Prolog As Integer, ByVal

StartGoal As String) As String

Public Declare Function CallGoal Lib "INT386W" (ByVal _ Prolog As Integer) As String

Public Declare Function TellGoal Lib "INT386W" (ByVal _ Prolog As Integer, ByVal

TellGoal As String) As String

155

Источник: https://studfile.net/preview/16708744/