Программирование на языке Prolog

Автор работы: Пользователь скрыл имя, 26 Мая 2013 в 07:27, курсовая работа

Краткое описание

Почти все существующие в настоящее время компьютеры, основаны на ранних, разработанных в 40-х годах идеях фон Неймана и его коллег. Машина фон Неймана содержит большую, состоящую из ячеек, память и процессор, снабженный локальной памятью, ячейки которой называются регистрами. Центральный процессор может загружать данные из памяти в регистры, выполнять арифметические или логические операции над содержимым регистров и отсылать значение из регистра в память.
Программа машины фон Неймана - это последовательность команд выполнения указанных операций вместе с дополнительным множеством команд управления, влияющих на выбор очередной команды.

Содержание

1 Структурное, функциональное и логическое программирование. 3
2 Основные конструкции языка 6
3 Ход работы 16
3.1Построение треугольника Паскаля 16
3.2 Работа со списками 24
3.3 Работа с внешними базами данных в Prolog 29
3.4 Задачи использующие структуру графа 34
3.5 Построение экспертной системы 39
3.6 Реализация головоломки о Ханоской башне 44
Список использованных источников 53

Вложенные файлы: 1 файл

Наша кеурсовик.docx

— 818.32 Кб (Скачать файл)

 

listall([],L,L).

listall([N|L1],L2,[N|L3]):-listall(L1,L2,L3).

 

  1. Нахождение максимального элемента: если список состоит из одного элемента, то он и является максимальным; если список состоит более, чем из одного элемента, то находим максимальный элемент в хвосте и сравниваем его с головой; если голова больше максимального элемента хвоста, то голова и является максимальным элементом списка, в противном случае максимальным элементом списка является максимальный элемент хвоста. Программный код представлен ниже:

 

max([X],X):- !.

max([H|Tail],H):-max(Tail,M),H>M,!.

max([_|Tail],M):-max(Tail,M).

 

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

 

dell([Max|Tail], Max, Tail):-!.

dell([H|Tail], Max, [H|Tail1]):-dell(Tail, Max, Tail1). 

 

Основной листинг программы  приведен ниже. Пример экранных форм программы  приведен на рисунок 12.

 

predicates

  dlg_spiski_eh : EHANDLER

max(ILIST, integer) % поиск максимального элемента

    % в объедененом списке

 dell(ILIST, integer, ILIST) % удаление максимального

     % элемента из списка

 slist_ilist(SLIST, ILIST) % перевод строки в число 

 listall(ILIST,ILIST,ILIST)   

clauses

 

  dlg_spiski_Create(Parent):-

win_CreateResDialog(Parent,dlg_spiski_DlgType,dlg_spiski_ResID,dlg_spiski_eh,0).

max([X],X):- !.

max([H|Tail],H):-max(Tail,M),H>M,!.

max([_|Tail],M):-max(Tail,M).

 

dell([], _, []):- !. % если список пуст, то конец 

dell([Max|Tail], Max, Tail):-!.

dell([H|Tail], Max, [H|Tail1]):-!,dell(Tail, Max, Tail1). 

 

slist_ilist([], []).

slist_ilist([HS|TS], [HI|TI]):- str_int(HS, HI),slist_ilist(TS, TI).

 

listall([],L,L).

listall([N|L1],L2,[N|L3]):-listall(L1,L2,L3).  

 

%BEGIN Spiski, clear _CtlInfo

  dlg_spiski_eh(_Win,e_Control(clear,_CtrlType,_CtrlWin,_CtlInfo),0):-

     HLb1 = win_GetCtlHandle(_Win, lb1),

   HLb2 = win_GetCtlHandle(_Win, lb2),

   HLbres = win_GetCtlHandle(_Win, lbres),

lbox_Clear(HLb1), % очищаем списки

lbox_Clear(HLb2),   

lbox_Clear(HLbres),             

!.

%END Spiski, clear _CtlInfo

 

%BEGIN Spiski, idc_cancel _CtlInfo

  dlg_spiski_eh(_Win,e_Control(idc_cancel,_CtrlType,_CtrlWin,_CtlInfo),0):-

win_Destroy(_Win), % закрываем диалог

!.

%END Spiski, idc_cancel _CtlInfo

 

%BEGIN Spiski, add1 _CtlInfo

  dlg_spiski_eh(_Win,e_Control(add1,_CtrlType,_CtrlWin,_CtlInfo),0):-

       HLb1 = win_GetCtlHandle(_Win, lb1),

HBe1 = win_GetCtlHandle(_Win, be1),

StrBe1 = win_GetText(HBe1), % получение значения из строки

StrBe1 <> "",   % проверка на «пустоту»

str_int(StrBe1, IntBe1),!, % проверка на число

lbox_Add(HLb1, StrBe1),  % добавляем в список значение

win_SetText(HBe1, ""),!.  % обнуляем значение строки

 

  dlg_spiski_eh(_Win,e_Control(add1,_CtrlType,_CtrlWin,_CtlInfo),0):-

dlg_Error("Добавляемое значение не должно быть пустым и строкой!"),   !. 

%END Spiski, add1 _CtlInfo

 

%BEGIN Spiski, del1 _CtlInfo

  dlg_spiski_eh(_Win,e_Control(del1,_CtrlType,_CtrlWin,_CtlInfo),0):-

   HLb1 = win_GetCtlHandle(_Win, lb1),

   lbox_GetSel(HLb1, _, IndList), % возвращает список индексов

   IndList = [I|_], % выбирает элемент из списка

      lbox_Delete(HLb1, I), % удаляем элемент из списка

!.

%END Spiski, del1 _CtlInfo

 

%BEGIN Spiski, add2 _CtlInfo

  dlg_spiski_eh(_Win,e_Control(add2,_CtrlType,_CtrlWin,_CtlInfo),0):-

       HLb2 = win_GetCtlHandle(_Win, lb2),

HBe2 = win_GetCtlHandle(_Win, be2),

StrBe2 = win_GetText(HBe2), % получение значения из строки

StrBe2 <> "",   % проверка на «пустоту»

str_int(StrBe2, IntBe2),!, % проверка на число

lbox_Add(HLb2, StrBe2),  % добавляем в список значение

win_SetText(HBe2, ""),!.  % обнуляем значение строки

 

  dlg_spiski_eh(_Win,e_Control(add2,_CtrlType,_CtrlWin,_CtlInfo),0):-

dlg_Error("Добавляемое значение не должно быть пустым и строкой!"), !.

%END Spiski, add2 _CtlInfo

 

%BEGIN Spiski, del2 _CtlInfo

  dlg_spiski_eh(_Win,e_Control(del2,_CtrlType,_CtrlWin,_CtlInfo),0):-  

   HLb2 = win_GetCtlHandle(_Win, lb2),

   lbox_GetSel(HLb2, _, IndList), % возвращает список индексов

   IndList = [I|_], % выбирает элемент из списка

      lbox_Delete(HLb2, I),!. % удаляем элемент из списка 

%END Spiski, del2 _CtlInfo

 

%BEGIN Spiski, result _CtlInfo

  dlg_spiski_eh(_Win,e_Control(result,_CtrlType,_CtrlWin,_CtlInfo),0):-

   HLb1 = win_GetCtlHandle(_Win, lb1),

   HLb2 = win_GetCtlHandle(_Win, lb2),

   HLbres = win_GetCtlHandle(_Win, lbres),

lbox_Clear(HLbres),   

   StrList1 = lbox_GetAll(HLb1), % возвращает список строк

   StrList2 = lbox_GetAll(HLb2), % возвращает список строк

% проверка на заполненость списков -----

   Count1 = lbox_CountAll(HLb1),

   Count2 = lbox_CountAll(HLb2),

   Count1 > 0,

   Count2 > 0,   !,

   slist_ilist(StrList1, IntList1),

   slist_ilist(StrList2, IntList2),

   listall(IntList1,IntList2,IntListRes),

lbox_Clear(HLbres), % очищаем список, так как будем производить изменения

% значений хранимый в списке

   max(IntListRes, Max), % ищем максимальный элемент

   dell(IntListRes, Max, Result), % удаляем его

   slist_ilist(StrResult, Result),

    lbox_Add(HLbres, StrResult), % заносим новый результат в список

    str_int(StrMax, Max),   

dlg_Note("Удаленный элемент", StrMax), !.

 

  dlg_spiski_eh(_Win,e_Control(result,_CtrlType,_CtrlWin,_CtlInfo),0):- 

dlg_Error("Оба списка должны быть заполнены!"),!.

 

 

Рисунок 12 - Результат работы Prolog-программы

 

 

3.3 Работа с внешними базами данных в Prolog

 

Цель:  Отработка практических навыков по работе с внешними базами данными (БД) в среде Visual Prolog 5.2

 

Примеры заданий:

 

  1. Не используя встроенный предикат asserta, написать программу, которая позволяет добавить новую запись в начало БД.
  2. Даны три таблицы БД. Выбранные пользователем записи двух первых таблиц добавить в третью.
  3. Даны две таблицы БД. Определить имеются ли в обоих таблицах одинаковые записи и в случае обнаружения удалить запись в одной из таблиц.
  4. Даны две таблицы БД. Поменять местами первую запись первой таблицы с последней записью второй таблицы. Поменять местами первую запись второй таблицы с последней записью первой таблицы.
  5. Обратить записи в таблице БД.
  6. Данные из списка занести в БД.
  7. В двух таблицах БД поменять местами все четные записи.
  8. Добавить запись в БД в указанное пользователем место.
  9. В таблице БД содержатся числовые данные. Произвести сортировку данных.

 

Пример  выполнения

 

Задание: Даны две таблицы БД. Дополнить первую таблицу данными второй.

 

Ход выполнения:

 

В среде Visual Prolog 5.2 создан соответствующий проект .

 

Логика  программы:

 

Работа с БД в Visual Prolog осуществляется с использованием встроенных предикатов assertz, asserta,consult и т.д. Для добавления первой таблицы данными второй таблицы достаточно воспользоваться предикатом добавления данных в конец таблицы assertz:

 

add2base([]):- !.

add2base([H|Tail]):-assertz(bs1(H)),!,add2base(Tail). 

 

Для сохранения базы во внешнем  файле необходимо использовать предикат save. Основной листинг программы приведен ниже. Пример экранных форм программы приведен на рисунок 13.

 

domains

s = string

i = integer

database - base1

bs1(s)

database - base2

bs2(s)

predicates

 dlg_base_eh : EHANDLER

 add2base(SLIST)

clauses

 dlg_base_Create(Parent):-

win_CreateResDialog(Parent,dlg_base_DlgType,dlg_base_ResID,dlg_base_eh,0).

add2base([]):- !.

add2base([H|Tail]):- assertz(bs1(H)),!,add2base(Tail). 

 

%MARK Base, new events

 

%BEGIN Base, e_Create

  dlg_base_eh(_Win,e_Create(_CreationData),0):-

       HLb1 = win_GetCtlHandle(_Win, lb1),

   HLb2 = win_GetCtlHandle(_Win, lb2),   

findall(X, bs1(X), Base2List1),  % заносим элементы из базы в список значений

findall(X, bs2(X), Base2List2),  

lbox_Add(HLb1, Base2List1),

lbox_Add(HLb2, Base2List2),

!.

%END Base, e_Create

 

%BEGIN Base, del2 _CtlInfo %кнопка удаления элементов из 2-го списка

  dlg_base_eh(_Win,e_Control(del2,_CtrlType,_CtrlWin,_CtlInfo),0):-

     HLb2 = win_GetCtlHandle(_Win, lb2),

   lbox_GetSel(HLb2, StrList, _),

   StrList = [S|_],

retract(bs2(S)),

findall(X, bs2(X), Base2List),

lbox_Clear(HLb2),

      lbox_Add(HLb2, Base2List),!.

%END Base, del2 _CtlInfo

 

%BEGIN Base, add2 _CtlInfo %кнопка добавления элементов во 2-й список

  dlg_base_eh(_Win,e_Control(add2,_CtrlType,_CtrlWin,_CtlInfo),0):-

       HLb2 = win_GetCtlHandle(_Win, lb2),

HBe2 = win_GetCtlHandle(_Win, be2),

StrBe2 = win_GetText(HBe2),

StrBe2 <> "", !,

lbox_Add(HLb2, StrBe2),

assertz(bs2(StrBe2)),

win_SetText(HBe2, ""),!.

 

  dlg_base_eh(_Win,e_Control(add2,_CtrlType,_CtrlWin,_CtlInfo),0):-

dlg_Error("Добавляемое значение не должно быть пустым!"),!.

%END Base, add2 _CtlInfo

 

%BEGIN Base, del1 _CtlInfo %кнопка удаления элементов из 1-го списка

  dlg_base_eh(_Win,e_Control(del1,_CtrlType,_CtrlWin,_CtlInfo),0):-

     HLb1 = win_GetCtlHandle(_Win, lb1),

   lbox_GetSel(HLb1, StrList, _),

   StrList = [S|_],

retract(bs1(S)),

findall(X, bs1(X), Base2List),

lbox_Clear(HLb1),

      lbox_Add(HLb1, Base2List),  !.

%END Base, del1 _CtlInfo

 

%BEGIN Base, add1 _CtlInfo %кнопка добавления элементов в 1-й список

  dlg_base_eh(_Win,e_Control(add1,_CtrlType,_CtrlWin,_CtlInfo),0):-

       HLb1 = win_GetCtlHandle(_Win, lb1),

HBe1 = win_GetCtlHandle(_Win, be1),

StrBe1 = win_GetText(HBe1),

StrBe1 <> "", !,

lbox_Add(HLb1, StrBe1),

assertz(bs1(StrBe1)),

win_SetText(HBe1, ""),!.

 

  dlg_base_eh(_Win,e_Control(add1,_CtrlType,_CtrlWin,_CtlInfo),0):-

dlg_Error("Добавляемое значение не должно быть пустым!"),

  !.

%END Base, add1 _CtlInfo

 

%BEGIN Base, ñombine _CtlInfo %кнопка объединения

  dlg_base_eh(_Win,e_Control(ñombine,_CtrlType,_CtrlWin,_CtlInfo),0):-

     HLb1 = win_GetCtlHandle(_Win, lb1),

   HLb2 = win_GetCtlHandle(_Win, lb2),

   Base2List2 = lbox_GetAll(HLb2),

   Count2 = lbox_CountAll(HLb2),

   Count2 > 0,!,

   lbox_Add(HLb1, Base2List2),

   add2base(Base2List2), !.

 

  dlg_base_eh(_Win,e_Control(ñombine,_CtrlType,_CtrlWin,_CtlInfo),0):-

dlg_Error("Невозможно объединить первую базу с пустой."),

!. 

%END Base, ñombine _CtlInfo

 

%BEGIN Base, clear _CtlInfo %кнопка очищения

  dlg_base_eh(_Win,e_Control(clear,_CtrlType,_CtrlWin,_CtlInfo),0):-

     HLb1 = win_GetCtlHandle(_Win, lb1),

   HLb2 = win_GetCtlHandle(_Win, lb2),

lbox_Clear(HLb1),

lbox_Clear(HLb2),   

retractall(bs1(_)),

retractall(bs2(_)),!.

%END Base, clear _CtlInfo

 

%BEGIN Base, idc_cancel _CtlInfo

  dlg_base_eh(_Win,e_Control(idc_cancel,_CtrlType,_CtrlWin,_CtlInfo),0):-

save("base1.txt", base1),

save("base2.txt", base2), % сохранение баз

win_Destroy(_Win),!.

 

 

Рисунок 13- Результат работы программы до и после объединения БД

 

Вывод:

В ходе выполнения работы я  освоил работу с внешними БД в Prolog.

 

 

 

3.4 Задачи использующие структуру графа

 

Цель:  Отработка практических навыков по решению задач, использующий структуру графа в среде Visual Prolog 5.2

 

Примеры заданий:

 

  1. Имеется БД о дорогах между 5 городами. Определить, как можно проехать из одного заданного пункта в другой.
  2. Дана БД о дорогах между городами. Определить в какие города можно добраться из заданного пункта.
  3. Из города N1 есть дороги в города N2, N3, N4, N5, из которых соединены дорогами N2 и N3, а также N4 и N5. Определить по какому маршруту можно послать посылку из одного заданного города в другой или определить, что данного маршрута не существует.
  4. Определить есть ли в БД «дороги» пункт, который соединен со всеми остальными.
  5. В доме имеется 6 комнат b,c,d,e,f,g. Имеются двери между комнатами: b и e, b и с, d и e, c и d, e и f, g и e.  В комнате g имеется телефон. Требуется помочь путнику отыскать комнату с телефоном, если путник первоначально находится в комнате b и в одну комнату нельзя заходить дважды.
  6. Дана БД о дорогах (X,Y,расстояние). Определить самый короткий путь из одного заданного пункта в другой.
  7. Написать программу, решающую транспортную задачу методом графов.

Информация о работе Программирование на языке Prolog