Будь умным!


У вас вопросы?
У нас ответы:) SamZan.net

модуль для работы сервера и модуль решателя для игры Восемь

Работа добавлена на сайт samzan.net: 2016-03-13

Поможем написать учебную работу

Если у вас возникли сложности с курсовой, контрольной, дипломной, рефератом, отчетом по практике, научно-исследовательской и любой другой работой - мы готовы помочь.

Предоплата всего

от 25%

Подписываем

договор

Выберите тип работы:

Скидка 25% при заказе до 22.5.2024

Отчёт SWI-Prolog программистов

Программисты: Минюров Евгений, Шарипов Денис.

1. Постановка задач

Задача: написать два серверных модуля: модуль для работы сервера и модуль решателя для игры «Восемь».

1.1 Функции модуля для работы сервера

  1.  Запуск сервера;
  2.  обмен сообщениями между сервером и клиентом;
  3.  остановка работы сервера.

1.2 Функции модуля решателя

  1.  Получение сообщения от клиента;
  2.  обработка полученного сообщения;
  3.  построение графа поиска решения игры;
  4.  передача сообщения клиенту.

2. Выполнение

2.1 Подготовительная часть

Для знакомства с сервером SWI-Prolog были разработаны следующие учебные программы:

  •  повторяющиеся вычисления;
  •  обмен сообщения с сервером SWI-Prolog;
  •  синхронные и асинхронные AJAX-запросы.

Исходный код этих программ приведён в Приложении (ссылка на приложение; смотри конец отчёта).

Написанные программы помогли получить общее представление о клиент-серверных технологиях конкретно в SWI-Prolog. Кроме того, с их помощью на начальных этапах осуществлялось предварительное тестирование программы на предмет работоспособности.

2.2 Основная часть

Все заданные функции спроектированных модулей были успешно реализованы. В процессе работы возникли небольшие трудности, поэтому совместно стал работать менеджер проекта Вахитов Антон.

Исходный код приведён в Приложении  (ссылка на приложение).


Приложение №1. Учебные программы

1. Повторяющиеся вычисления

1.1 Операторы fail и repeat

run:-

 repeat,nl,

 write('Вводите слова, я буду повторять их'), nl,

 write('Если хотите остановить меня, введите stop.'), nl,

 read(X), check(X),

nl,write('Ok, bye!').

check(stop).

check(X):-

X \= 'stop', nl,write(X),

fail.

?- run.

1.2 Рекурсивный вызов функции

list1([student('Ivanov','Otlichnik'),

      student('Petrov','Horoshist'),

      student('Ivanov','Troechik')      ]).

run:- list1(Ls),

     show_list(Ls),

     nl,write('OK, bye').

show_list([]).

show_list([H|Ts]):-

process1(H),

show_list(Ts).

process1(student(Name,Mark)):-

nl,

write(Name),write(' - '),write(Mark).

?- run.

2. Обмен сообщения с сервером SWI-Prolog

2.1 Отображение текста

:- use_module(library(http/thread_httpd)).

:- use_module(library(http/http_dispatch)).

:- http_handler(root(hello_world), say_hi, []).

server(Port) :-

       http_server(http_dispatch, [port(Port)]).

say_hi(_Request) :-

       format('Content-type: text/plain~n~n'),

       format('Hello World!~n').

2.2 Обмен html-сообщениями

:- use_module(library(http/thread_httpd)).

:- use_module(library(http/http_dispatch)).

:- use_module(library(http/http_error)).

:- use_module(library(http/html_write)).

:- http_handler('/', say_hi, []).

server(Port) :-

       http_server(http_dispatch, [port(Port)]).

say_hi(_Request):-

reply_html_page([title('Buttons'),h1('Это обмен сообщениями')],

[form('name="ButtonsPlace"',''),

 script('type="text/javascript"', 'function Add()

{var element=document.createElement("input");

element.setAttribute("type", "radio"); element.setAttribute("name", "feed");

document.ButtonsPlace.appendChild(element);

var label=document.createTextNode("Line");

document.ButtonsPlace.appendChild(label);

var br = document.createElement("br");

document.ButtonsPlace.appendChild(br);}'),

button('onclick="Add()"','Make')

 ]).

3. Синхронные и асинхронные AJAX-запросы

3.1 Синхронный AJAX-запрос

:- use_module(library(http/thread_httpd)).

:- use_module(library(http/http_dispatch)).

:- use_module(library(http/http_error)).

:- use_module(library(http/html_write)).

:- http_handler('/', say_hi, []).

server(Port) :-

       http_server(http_dispatch, [port(Port)]).

say_hi(_Request):-

reply_html_page([title('Buttons'),h1('Это обмен сообщениями')],

[form('name="ButtonsPlace"',''),

 script('type="text/javascript"', 'function Http()

       { var xmlhttp = new XMLHttpRequest();  xmlhttp.open("Get","/",false);

         xmlhttp.send(); alert(xmlhttp.status); alert(xmlhttp.responseText);  }'),

  button('name=ad onclick="Http()"','Make')]).

3.2 Асинхронный AJAX-запрос

:- use_module(library(http/thread_httpd)).

:- use_module(library(http/http_dispatch)).

:- use_module(library(http/http_error)).

:- use_module(library(http/html_write)).

:- http_handler('/', say_hi, []).

server(Port) :-

       http_server(http_dispatch, [port(Port)]).

say_hi(_Request):-

reply_html_page([title('Buttons'),h1('Это обмен сообщениями')],

[form('name="ButtonsPlace"',''),

 script('type="text/javascript"', 'function Http()

       { var xmlhttp = new XMLHttpRequest();  xmlhttp.open("Get","/",true);

         xmlhttp.send(); alert(xmlhttp.status); alert(xmlhttp.responseText);  }'),

  button('name=ad onclick="Http()"','Make')]).


Приложение №2

1. Модуль решателя задач

:- module(p8,[g/1]).

:-use_module(srv8).

/***************************************************************************

пролог-программа эвристического поиска: головоломка "Игра в восемь"

***************************************************************************/

:- dynamic dN/1, dmax_f/1.

/*

goal(StState) :-

 start, % запускаем сервер

 g(StState). % решаем задачу

*/

g(StartState):-

 retractall(dN(_)),

 retractall(dmax_f(_)),

 assert(dN(0)),

 assert(dmax_f(100)),

 %startState(StartState), % статический тест

 evrpoisk(StartState,Reshenie),

 %delete(Reshenie,StartState,Reshenie1),%только при запуске кнопкой

 reverse(Reshenie,Reshenie2),  %reverse(Reshenie1,Reshenie2),

 pokazresh2(Reshenie2).

evrpoisk(Start,Reshs):-

 dmax_f(Fmax),

 rasshirit([],lis(Start,0/0),Fmax,_,yes,Reshs).

rasshirit(Ps,lis(B,_),_,_,yes,[B|Ps]):-

 addN,

 dmax_f(Fmax), checkM(B,Fmax).

rasshirit(Ps,lis(B,F/G),Predel,Der1,IsResh,Reshs):-

 F =< Predel,

 ( bagof(B1/C, arc2(B,B1,C,Ps), Preemniks),!,

   preemspis(G,Preemniks,DDs),

   opt_f(DDs,F1),

   rasshirit(Ps,der(B,F1/G,DDs),Predel,Der1,IsResh,Reshs);

   IsResh=nikogda  %нет преемников - тупик

 ).

rasshirit(Ps,der(B,F/G,[D|DDs]),Predel,Der1,IsResh,Reshs):-

 F =< Predel,

 opt_f(DDs,OF),

 minn(Predel,OF,Predel1),

 rasshirit([B|Ps],D,Predel1,D1,IsResh1,Reshs),

 prodoljit(Ps,der(B,F/G,[D1|DDs]),Predel,Der1,IsResh1,IsResh,Reshs).

rasshirit(_,der(_,_,[]),_,_,nikogda,_):- !. %тупиковое дерево - нет решений

rasshirit(_,Der,Predel,Der,no,_):- f(Der,F), F > Predel. %рост остановлен

arc2(B,B1,C,Ps):- arc(B,B1,C), not(member(B1,Ps)). %антицикл

prodoljit(_,_,_,_,yes,yes,_).  %Reshs

prodoljit(Ps,der(B,_/G,[D1|DDs]),Predel,Der1,IsResh1,IsResh,Reshs):-

 ( IsResh1=no,

   vstav(D1,DDs,HDDs);

   IsResh1=nikogda,

   HDDs = DDs

 ),

 opt_f(HDDs,F),

 rasshirit(Ps,der(B,F/G,HDDs),Predel,Der1,IsResh,Reshs).

preemspis(_,[],[]).

preemspis(G0,[B/C|BBs],DDs):-

 G is G0 + C,

 h(B,H),

 F is G + H,

 preemspis(G0,BBs,DD1s),

 vstav(lis(B,F/G),DD1s,DDs).

%вставка дерева D в список деревьев DDs

%с сохранением упорядоченности по f-оценкам:

vstav(D,DDs,[D|DDs]):-

 f(D,F),

 opt_f(DDs,F1),

 F =< F1, !.

vstav(D,[D1|DDs],[D1|DD1s]):-

 vstav(D,DDs,DD1s).

%получение f-оценки:

f(lis(_,F/_),F). %f-оценка листа

f(der(_,F/_,_),F). %f-оценка дерева

opt_f([D|_],F):-  f(D,F).      %наилучшая f-оценка для списка деревьев

opt_f([],Fmax):-  dmax_f(Fmax). %плохая f-оценка: нет деревьев

minn(X,Y,X):- X =< Y, !.

minn(_,Y,Y).

%--------- отображение решающего пути через интерфейс к C++ -----------

pokazresh2([]).

pokazresh2([H|Ts]):-

 process1(H),

 pokazresh2(Ts).

process1(Ls):-

 convert1(Ls,L1s), %конвертируем список операторов X/Y в список строк

 concat_atom(L1s,',',AL),

 sendToC(AL,Answer),

 check(Answer).

convert1([],[]).

convert1([H1|T1s],[H2|T2s]):-

 H1 = X/Y, %здесь символ "/" явл-ся ОПЕРАТОРОМ: надо превратить в строку

 atom_concat(X, '/', X1),

 atom_concat(X1, Y, XY),

 XY = H2,

 convert1(T1s,T2s).

check(1).

check(0).  %потом сделать: check(0):- halt.

addN:-   %RTTI + страховочный порог

 dN(N),

 integer(N),

 N < 20000,  %N < 28000,% предел ~30тыс. узлов

 N1 is N+1,

 retract(dN(_)),

 assert(dN(N1)),!.

addN:-

 %nl,write('Задача НЕ решена: размер графа больше 20000 узлов'),

 %nl,write('Вот начало решения:'),

 retract(dmax_f(_)), assert(dmax_f(1)),!.

checkM(_,Fmax):- Fmax =< 1, !.

checkM(B,_):- goalFin(B).

%====== динамически заданный эвристический граф для задачи "Игра в 8" ======

% задача решается методом разделения на подзадачи: стратегия "Разделяй и Властвуй"

arc([Pusto|Ls],[Fishka|L1s],1):-  %стоимости всех дуг равны 1

 perest(Pusto,Fishka,Ls,L1s).    %переставив Pusto и Fishka, получаем L1s

perest(P,F,[F|Ls],[P|Ls]):- rasst(P,F,1).

perest(P,F,[F1|Ls],[F1|L1s]):- perest(P,F,Ls,L1s).

rasst(X/Y,X1/Y1,R):-   %"расстояние" между клетками

 rasst1(X,X1,Rx),

 rasst1(Y,Y1,Ry),

 R is Rx + Ry.

rasst1(A,B,R):-

 R is A - B, R >= 0, !;

 R is B - A.

%эвристическая оценка h равна сумме расстояний фишек от их "целевых" клеток

%плюс "степень упорядоченности", умноженная на 3:

h([_|Ls],H):-          %h([Pusto|Ls],H)     /*Singleton variables*/

 goalFin([_|GLs]), %goal1([Pusto1|GLs]) /*Singleton variables*/

 sumrasst(Ls,GLs,R),

 uporyad(Ls,Up),

 %H is R + 3*Up.

 %H is R + 2*Up. %путь короче, но ищет дольше

 H is R + Up.   %путь еще короче, но ищет еще дольше

sumrasst([],[],0). %т.е. число фишек не на своем месте

sumrasst([F|Ls],[F1|L1s],R):-

 rasst(F,F1,R1),

 sumrasst(Ls,L1s,R2),

 R is R1 + R2.

uporyad([First|Ls],U):-

 upor2([First|Ls],First,U).

upor2([F1,F2|Ls],_,U):-

 ochki2(F1,F2,U1),

 upor2([F2|Ls],_,U2),

 U is U1 + U2.

upor2([Last],_,U):- ochki2(Last,_,U).

ochki2(2/2,_,1):- !.   %фишка в центре - 1 очко

ochki2(1/3,2/3,0):- !. %правильная последовательность - 0 очков

ochki2(2/3,3/3,0):- !.

ochki2(3/3,3/2,0):- !.

ochki2(3/2,3/1,0):- !.

ochki2(3/1,2/1,0):- !.

ochki2(2/1,1/1,0):- !.

ochki2(1/1,1/2,0):- !.

ochki2(1/2,1/3,0):- !.

ochki2(_,_,2):- !.     %неправильная последовательность - 2 очка

goalFin([2/2,1/3,2/3,3/3,3/2,3/1,2/1,1/1,1/2]). %финишная ситуация

sendToC(AL,Answer):- nl,web_write(AL), Answer=1.

startState([3/2,1/2,1/3,3/3,2/2,3/1,2/1,1/1,2/3]). % статика, L=6ходов

%===========================================================================

%?- start(p8:g([3/2,1/2,1/3,3/3,2/2,3/1,2/1,1/1,2/3])).

%?- start, g([3/2,1/2,1/3,3/3,2/2,3/1,2/1,1/1,2/3]).

%?- goal([3/2,1/2,1/3,3/3,2/2,3/1,2/1,1/1,2/3]).

2. Модуль сервера

:- module(srv8,

         [

          start/0,  %start/1,

          s/0, %stop/0,

          web_write/1,

          debug_print/2

         ]).

:-use_module(library(http/thread_httpd)).

:-use_module(library(http/http_dispatch)).

:-use_module(library(http/http_json)).

:-use_module(library(http/http_files)).

:-use_module(p8).

% загружаем конфигурацию

%:-dynamic solver/1. % только при start/1

:-dynamic web_log/1.

debug_print(Format, Args) :-

 format(user, Format, Args).

web_g(Request) :-

 purgateAllSrv,

 wstat(Request).

wstat([_,_,_,_,_,_,_,search([X1])|_]):-

 term_to_atom(X1,A),

 atom_to_chars(A,Str),

 wstat3(Str,Str2),

 parse(Str2,[],X3),

% del(X3,X4),

 wstat2(X3).

del([_|Hs],Hs).

parse([],X3,X3).

parse([X,Z,Y,_|Hs],X3,X4):-

   %  S=[X,Z,Y],

   %  name(At,S),

     atom_codes(X2,[X]),

     atom_codes(Y2,[Y]),

     conver(X2,I1),

     conver(Y2,I2),

     append(X3,[I1/I2],L3),

     parse(Hs,L3,X4).

conver('1',1).

conver('2',2).

conver('3',3).

wstat3([_H1,_H2,_H3,_H4,_H5|X1],X1).

wstat2(X4):-

debug_print('запрос: ~p ~n',[X4]),

g(X4),

findall(X, web_log(X), Xs),

reply_json(Xs).

web_clear(_Request) :-

 debug_print('очищаем историю сообщений Msg ~n', []),

 retractall(web_log(_)),

 format('Content-Type: text/plain~n~n', []).

start_web(Port) :-

 http_handler('/', http_reply_from_files('www', []), [prefix]),

 http_handler('/proba', web_g, []),

 http_handler('/clear', web_clear, []),

 http_server(http_dispatch, [port(Port)]).

start :-

 purgateAllSrv,

 start_web(8080).

purgateAllSrv :-

       retractall(web_log(_)).

       %retractall(solver(_)).

web_write(Msg) :-

       format(atom(A), '~p', [Msg]), % in=Msg, out=A

       assert(web_log(A)).

web_format(Format, Args) :- format(atom(Msg), Format, Args), web_write(Msg).

s :-

web_clear(_Request),

       %thread_httpd:http_stop_server(8080,[]),

       http_stop_server(8080,[]),

       halt,!.

?- start.




1. яку інформацію про номери і фамілію проживаючих гостей особам що не працюють в готелі; за всіма довідками по
2. судебная практика
3. Учет готовой продукции и ее реализация
4. Реферат- Математика и информатика в проведении гуманитарных исследований
5. Математик И
6. Руська Правда як джерело з історії України її історичне значення
7. Ода на 1747 Дерзайте ныне ободренны Раченьем вашим показать Что может собственных Платонов И быс
8. психологическом подходе к изучению управления
9. Вторая половинка есть у мозга жопы и таблетки
10. Сталепромышленная компания ~ Красноярск.
11. David Hilbert.html
12. Искусство импрессионистов
13. Екологічні проблеми міського середовища і містобудування.html
14. тема знаний о государственноправовых явлениях соответствующих своему понятию и с естественной необходимос
15. Электроснабжение деревни Анисовка
16. Роль банков
17. вариантов формулы для расчета работы тока- По закону сохранения энергии- работа равна изменению энергии
18. компьютерлі жел
19. Курсовая работа- Природоохранная защита сахарной свеклы от вредителей, болезней и сорняков с помощью химических средств
20. во смен Колво рабочих в смену Потребность в машинах