-
Notifications
You must be signed in to change notification settings - Fork 0
/
server.pl
104 lines (83 loc) · 2.73 KB
/
server.pl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
:- use_module(library(http/http_dispatch)).
:- use_module(library(http/http_server)).
:- use_module(library(http/http_json)).
:- use_module(library(uuid)).
:- initialization
server(5050).
server(Port) :-
http_server(http_dispatch, [port(Port)]).
:- http_handler(root(.), http_reply_file('./web/index.html', []), []).
:- http_handler(root('script.js'), http_reply_file('./web/script.js', []), []).
:- http_handler(root('style.css'), http_reply_file('./web/style.css', []), []).
:- http_handler(root(paths), paths_handler, []).
:- dynamic
cell/3,
limits/2.
paths_handler(Request) :-
http_read_json_dict(Request, _{
limits: Limits, start: Start, finish: Finish, walls: Walls}),
uuid(Id),
assert_data(Id, Limits, Start, Finish, Walls),
call_with_time_limit(10, findall(Path, path(Id, Path), Paths)),
retract_data(Id),
paths_sort(Paths, SortedPaths),
dict_create(Data, _, [paths-SortedPaths]),
dict_create(Response, _, [data-Data, format-json, opcode-text]),
reply_json_dict(Response).
assert_data(Id, Limits, Start, Finish, Walls) :-
assertz(limits(Id, Limits)),
assertz(cell(Id, Finish, finish)),
assertz(cell(Id, Start, start)),
assert_walls(Id, Walls).
assert_walls(_, []) :- !.
assert_walls(Id, [Wall|WallsTail]) :-
assertz(cell(Id, Wall, wall)),
assert_walls(Id, WallsTail).
retract_data(Id) :-
retract(limits(Id, _)),
retractall(cell(Id, _, _)).
paths_sort(Paths, Sorted) :-
maplist(path_len, Paths, PathsWithLen),
keysort(PathsWithLen, SortedPathsWithLen),
maplist(path_without_len, SortedPathsWithLen, Sorted).
path_len(Path, Len-Path) :-
length(Path, Len).
path_without_len(_-Path, Path).
outside([X, _]) :-
X < 0.
outside([X, _]) :-
limits(_, [LimitX, _]),
X > LimitX.
outside([_, Y]) :-
Y < 0.
outside([_, Y]) :-
limits(_, [_, LimitY]),
Y > LimitY.
asrt(Id, Next, Visited, Result) :-
not(cell(Id, Next, wall)),
not(outside(Next)),
not(member(Next, Visited)),
append(Visited, [Next], NewVisited),
step(Id, Next, NewVisited, Result).
step(Id, From, Visited, Result) :-
cell(Id, From, finish),
Result = Visited, !.
step(Id, [FromX, FromY], Visited, Result) :-
NextX is FromX + 1,
Next = [NextX, FromY],
asrt(Id, Next, Visited, Result).
step(Id, [FromX, FromY], Visited, Result) :-
NextX is FromX - 1,
Next = [NextX, FromY],
asrt(Id, Next, Visited, Result).
step(Id, [FromX, FromY], Visited, Result) :-
NextY is FromY + 1,
Next = [FromX, NextY],
asrt(Id, Next, Visited, Result).
step(Id, [FromX, FromY], Visited, Result) :-
NextY is FromY - 1,
Next = [FromX, NextY],
asrt(Id, Next, Visited, Result).
path(Id, Result) :-
cell(Id, Start, start),
step(Id, Start, [Start], Result).