Волченков Логическое программирование язык пролог 2015
.pdf%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
Public Declare Sub ExitGoal Lib "INT386W" (ByVal _ Prolog As Integer)
Sub ЧастичноВычислитьВыражение()
Dim S1 As String, S2 As String, S As String, N As Integer G = "valuate_expretion" ' Имя программы на Прологе
Dim x As String
' Dim OutString As Object
Prolog_Renamed = LoadProlog("/H100000 /R100000 /B100000 /L100000")
If Prolog_Renamed < 0 Then MsgBox "LoadProlog Error " & _ Str(Prolog_Renamed) & _
"!", MsgBoxStyle.Critical
End
End If
G = "consult(" & G & "). "
x = InitGoal(Prolog_Renamed, G)
x = CallGoal(Prolog_Renamed) ExitGoal (Prolog_Renamed)
x = InitGoal(Prolog_Renamed, "an. ")
' an – это имя целевого предиката
OutString = CallGoal(Prolog_Renamed) HaltProlog (Prolog_Renamed)
End Sub
Код 10.8. Модуль Листа книги Excel
Private Sub ButtonПоказатьПользовательскуюФорму_Click()
UserForm1.Show
End Sub
Код 10.9. Модуль формы UserForm1
Private Sub Button_ЗагрузитьПрологПрограмму_Click()
Open "valuate_expretion.pl" For Input As #1
Dim S As String
Do Until EOF(1)
Line Input #1, S
156
TextBox1.Text = TextBox1.Text & vbCrLf & S Loop
Close #1 End Sub
Private Sub Button_ЗагрузитьИсходноеВыражение_Click() Open "string.txt" For Output As #2
Print #2, TextBox2.Text Print #2, vbCrLf
Close #2 End Sub
Private Sub Button_Вычислить_ПоказатьРезультат_Click()
Call ЧастичноВычислитьВыражение
Open "struct.txt" For Input As #3 Dim S1 As String, S2 As String Line Input #3, S1
Line Input #3, S2
TextBox3.Text = "Анализируемое выражение: " & _ vbCrLf & S1 & vbCrLf & vbCrLf & _
"Значение выражения: " & vbCrLf & S2 Close #3
End Sub
Программа на Прологе для данного примера не нуждается в представлении: она показана на рисунке 10.7 – в левом текстовом поле на пользовательской форме.
Вывод: Интерфейс декларативного языка Пролог и императивного визуального языка Visual Basic открывает программистам ши-
рокие перспективы сочетать возможности эффективной реализации символьных преобразований (Пролог) с возможностями реализации алгоритмически сложных вычислений и визуализации – в частности, применения машинной графики (Visual Basic).
157
Литература, источники в интернете
1.Robinson J. A., A machine-oriented logic based on the resoulution principle, Journal of the ACM, v. 12, January 1965. pp. 23-41.
2. A. Colmerauer, Ph. Roussel. The birth of Prolog. The ACM Digital Library. Book: History of programming languages-II. ACM, New York, NY, USA. 1996. – pp. 331-367.
3.Alain Colmerauer and Philippe Roussel. The birth of Prolog. URL: http://alain.colmerauer.free.fr/alcol/ArchivesPublications/PrologHist ory/ 19november92.pdf
4.Клоксин У., Меллиш К. Программирование на языке Пролог/ Пер. с англ.; Под ред. А.К.Платонова и Ю.М.Лазутина. М.:
Мир, 1987. – 336 с.
5.Стобо Дж. Язык программирования Пролог/ Пер. с англ.; Под ред. Н.Г.Волченкова. М.: Радио и связь, 1993. – 368 с.
6.Малпас Дж. Реляционный язык Пролог и его применение/ Пер. с англ.; Под ред. В.Н.Соболева. М.: Наука, 1990. – 464 с.
7. Стерлинг Л., Шапиро Э. Искусство программирования на
языке Пролог/ Пер. с англ.; Под ред. Ю.Г.Дадаева. М.: Мир,
1990. – 235 с.
8.Чери С., Готлоб Г., Танка Л. Логическое программирование и
базы данных/ Пер. с англ.; Под ред. Л.А.Калиниченко. М.: Мир,
1992. – 352 с.
9.Братко И. Алгоритмы искусственного интеллекта на языке PROLOG/ Пер. с англ.; Под ред. К.А.Птицина. М.: Издательский дом «Вильямс», 2004. – 640 с.
10.Сергиевский Г.М., Волчёнков Н.Г. Функциональное и логическое программирование: учебное пособие для студ. высш. учеб. заведений. М.: Издательский центр «Академия», 2010. – 320 с.
158