Include Paulo Moura's Logtalk OO LP system
git-svn-id: https://yap.svn.sf.net/svnroot/yap/trunk@53 b08c6af1-5177-4d33-ba66-4b1c6b8b522a
This commit is contained in:
20
Logtalk/examples/searching/NOTES
Normal file
20
Logtalk/examples/searching/NOTES
Normal file
@@ -0,0 +1,20 @@
|
||||
=================================================================
|
||||
Logtalk - Object oriented extension to Prolog
|
||||
Release 2.8.4
|
||||
|
||||
Copyright (c) 1998-2001 Paulo Moura. All Rights Reserved.
|
||||
=================================================================
|
||||
|
||||
To load all objects in this example consult the searching.loader utility
|
||||
file (note that the *.loader files are Prolog files).
|
||||
|
||||
You will need to also load the objects in the roots example.
|
||||
|
||||
You will also need to load the following files in the library directory:
|
||||
dates.loader, types.loader, events.loader, metapredicates.loader, and
|
||||
hierarchies.loader.
|
||||
|
||||
Some of the code in this folder is adopted from the book "Prolog Programming
|
||||
for Artificial Intelligence" by Ivan Bratko.
|
||||
|
||||
The object "performance" only provides correct results for the first solution.
|
248
Logtalk/examples/searching/SCRIPT
Normal file
248
Logtalk/examples/searching/SCRIPT
Normal file
@@ -0,0 +1,248 @@
|
||||
=================================================================
|
||||
Logtalk - Object oriented extension to Prolog
|
||||
Release 2.8.4
|
||||
|
||||
Copyright (c) 1998-2001 Paulo Moura. All Rights Reserved.
|
||||
=================================================================
|
||||
|
||||
|
||||
% farmer, cabbage, goat and wolf problem
|
||||
|
||||
| ?- farmer::initial_state(Initial), depth_first(10)::solve(farmer, Initial, Path), farmer::print_path(Path).
|
||||
|
||||
cgwf.<__>..........____
|
||||
c_w_..........<__>.f_g_
|
||||
c_wf.<__>..........__g_
|
||||
__w_..........<__>.fcg_
|
||||
_gwf.<__>.........._c__
|
||||
_g__..........<__>.fc_w
|
||||
_g_f.<__>.........._c_w
|
||||
____..........<__>.fcgw
|
||||
|
||||
Path = [(north,north,north,north),(north,south,north,south),(north,south,north,north),(south,south,north,south),(south,north,north,north),(south,north,south,south),(south,north,south,north),(south,south,south,south)],
|
||||
Initial = (north,north,north,north) ?
|
||||
|
||||
yes
|
||||
|
||||
|
||||
% missionaires and cannibals problem, solved using a hill-climbing strategy
|
||||
|
||||
| ?- miss_cann::initial_state(Initial), hill_climbing(16)::solve(miss_cann, Initial, Path, Cost), miss_cann::print_path(Path).
|
||||
|
||||
MMMCCC.<__>..........
|
||||
MMCC..........<__>.MC
|
||||
MMMCC.<__>..........C
|
||||
MMM..........<__>.CCC
|
||||
MMMC.<__>..........CC
|
||||
MC..........<__>.MMCC
|
||||
MMCC.<__>..........MC
|
||||
CC..........<__>.MMMC
|
||||
CCC.<__>..........MMM
|
||||
C..........<__>.MMMCC
|
||||
CC.<__>..........MMMC
|
||||
..........<__>.MMMCCC
|
||||
|
||||
Cost = 15,
|
||||
Path = [((3,3),esq,0,0),((2,2),dir,1,1),((3,2),esq,0,1),((3,0),dir,0,3),((3,1),esq,0,2),((1,1),dir,2,2),((2,2),esq,1,1),((0,2),dir,3,1),((0,3),esq,3,0),((0,1),dir,3,2),((0,2),esq,3,1),((0,0),dir,3,3)],
|
||||
Initial = ((3,3),esq,0,0)
|
||||
yes
|
||||
|
||||
|
||||
% same problem as above with the addition of a monitor to measure hill-climbing performance
|
||||
|
||||
| ?- performance::init, miss_cann::initial_state(Initial), hill_climbing(16)::solve(miss_cann, Initial, Path, Cost), miss_cann::print_path(Path), performance::report.
|
||||
|
||||
MMMCCC.<__>..........
|
||||
MMCC..........<__>.MC
|
||||
MMMCC.<__>..........C
|
||||
MMM..........<__>.CCC
|
||||
MMMC.<__>..........CC
|
||||
MC..........<__>.MMCC
|
||||
MMCC.<__>..........MC
|
||||
CC..........<__>.MMMC
|
||||
CCC.<__>..........MMM
|
||||
C..........<__>.MMMCC
|
||||
CC.<__>..........MMMC
|
||||
..........<__>.MMMCCC
|
||||
solution length: 12
|
||||
number of state transitions: 27
|
||||
ratio solution length / state transitions: 0.4444444444444444
|
||||
minimum branching degree: 2
|
||||
average branching degree: 2.5555555555555554
|
||||
maximum branching degree: 3
|
||||
time: 0.067999999999756255
|
||||
|
||||
Cost = 15,
|
||||
Path = [((3,3),esq,0,0),((2,2),dir,1,1),((3,2),esq,0,1),((3,0),dir,0,3),((3,1),esq,0,2),((1,1),dir,2,2),((2,2),esq,1,1),((0,2),dir,3,1),((0,3),esq,3,0),((0,1),dir,3,2),((0,2),esq,3,1),((0,0),dir,3,3)],
|
||||
Initial = ((3,3),esq,0,0) ?
|
||||
|
||||
yes
|
||||
|
||||
|
||||
% water jugs problem solved using a breadth and a depth first strategy, with performance monitors
|
||||
% it's interesting to compare the results
|
||||
|
||||
| ?- performance::init, water_jug::initial_state(Initial), breadth_first(6)::solve(water_jug, Initial, Path), water_jug::print_path(Path), performance::report.
|
||||
|
||||
4-gallon jug: 0
|
||||
3-gallon jug: 0
|
||||
|
||||
4-gallon jug: 0
|
||||
3-gallon jug: 3
|
||||
|
||||
4-gallon jug: 3
|
||||
3-gallon jug: 0
|
||||
|
||||
4-gallon jug: 3
|
||||
3-gallon jug: 3
|
||||
|
||||
4-gallon jug: 4
|
||||
3-gallon jug: 2
|
||||
|
||||
4-gallon jug: 0
|
||||
3-gallon jug: 2
|
||||
|
||||
solution length: 6
|
||||
number of state transitions: 105
|
||||
ratio solution length / state transitions: 0.05714285714285714
|
||||
minimum branching degree: 2
|
||||
average branching degree: 3.6315789473684212
|
||||
maximum branching degree: 4
|
||||
time: 0.20000000000027285
|
||||
|
||||
Path = [(0,0),(0,3),(3,0),(3,3),(4,2),(0,2)],
|
||||
Initial = (0,0) ?
|
||||
|
||||
yes
|
||||
|
||||
|
||||
| ?- performance::init, water_jug::initial_state(Initial), depth_first(10)::solve(water_jug, Initial, Path), water_jug::print_path(Path), performance::report.
|
||||
|
||||
4-gallon jug: 0
|
||||
3-gallon jug: 0
|
||||
|
||||
4-gallon jug: 4
|
||||
3-gallon jug: 0
|
||||
|
||||
4-gallon jug: 4
|
||||
3-gallon jug: 3
|
||||
|
||||
4-gallon jug: 0
|
||||
3-gallon jug: 3
|
||||
|
||||
4-gallon jug: 3
|
||||
3-gallon jug: 0
|
||||
|
||||
4-gallon jug: 3
|
||||
3-gallon jug: 3
|
||||
|
||||
4-gallon jug: 4
|
||||
3-gallon jug: 2
|
||||
|
||||
4-gallon jug: 0
|
||||
3-gallon jug: 2
|
||||
|
||||
solution length: 8
|
||||
number of state transitions: 12
|
||||
ratio solution length / state transitions: 0.6666666666666666
|
||||
|
||||
|
||||
|
||||
minimum branching degree: 1
|
||||
average branching degree: 2.0
|
||||
maximum branching degree: 3
|
||||
time: 0.021999999999934516
|
||||
|
||||
Path = [(0,0),(4,0),(4,3),(0,3),(3,0),(3,3),(4,2),(0,2)],
|
||||
Initial = (0,0) ?
|
||||
|
||||
yes
|
||||
|
||||
|
||||
% eight puzzle solved using a hill-climbing strategy
|
||||
|
||||
| ?- performance::init, eight_puzzle::initial_state(five_steps, Initial), hill_climbing(25)::solve(eight_puzzle, Initial, Path, Cost), eight_puzzle::print_path(Path), performance::report.
|
||||
|
||||
283
|
||||
164
|
||||
7 5
|
||||
|
||||
283
|
||||
1 4
|
||||
765
|
||||
|
||||
2 3
|
||||
184
|
||||
765
|
||||
|
||||
23
|
||||
184
|
||||
765
|
||||
|
||||
123
|
||||
84
|
||||
765
|
||||
|
||||
123
|
||||
8 4
|
||||
765
|
||||
solution length: 6
|
||||
number of state transitions: 15
|
||||
ratio solution length / state transitions: 0.4
|
||||
minimum branching degree: 2
|
||||
average branching degree: 3.1333333333333333
|
||||
maximum branching degree: 4
|
||||
time: 0.050000000000181899
|
||||
|
||||
Cost = 5,
|
||||
Path = [[2/1,1/2,1/3,3/3,3/2,3/1,2/2,1/1,2/3],[2/2,1/2,1/3,3/3,3/2,3/1,2/1,1/1,2/3],[2/3,1/2,1/3,3/3,3/2,3/1,2/1,1/1,2/2],[1/3,1/2,2/3,3/3,3/2,3/1,2/1,1/1,2/2],[1/2,1/3,2/3,3/3,3/2,3/1,2/1,1/1,2/2],[2/2,1/3,2/3,3/3,3/2,3/1,2/1,1/1,1/2]],
|
||||
Initial = [2/1,1/2,1/3,3/3,3/2,3/1,2/2,1/1,2/3] ?
|
||||
|
||||
yes
|
||||
|
||||
|
||||
% eight puzzle solved using a best-first strategy
|
||||
|
||||
| ?- performance::init, eight_puzzle::initial_state(five_steps, Initial), best_first(25)::solve(eight_puzzle, Initial, Path, Cost), eight_puzzle::print_path(Path), performance::report.
|
||||
|
||||
283
|
||||
164
|
||||
7 5
|
||||
|
||||
283
|
||||
1 4
|
||||
765
|
||||
|
||||
2 3
|
||||
184
|
||||
765
|
||||
|
||||
23
|
||||
184
|
||||
765
|
||||
|
||||
123
|
||||
84
|
||||
765
|
||||
|
||||
123
|
||||
8 4
|
||||
765
|
||||
solution length: 6
|
||||
number of state transitions: 15
|
||||
ratio solution length / state transitions: 0.4
|
||||
minimum branching degree: 2
|
||||
average branching degree: 3.1333333333333333
|
||||
maximum branching degree: 4
|
||||
time: 0.046000000000276486
|
||||
|
||||
Cost = 5,
|
||||
Path = [[2/1,1/2,1/3,3/3,3/2,3/1,2/2,1/1,2/3],[2/2,1/2,1/3,3/3,3/2,3/1,2/1,1/1,2/3],[2/3,1/2,1/3,3/3,3/2,3/1,2/1,1/1,2/2],[1/3,1/2,2/3,3/3,3/2,3/1,2/1,1/1,2/2],[1/2,1/3,2/3,3/3,3/2,3/1,2/1,1/1,2/2],[2/2,1/3,2/3,3/3,3/2,3/1,2/1,1/1,1/2]],
|
||||
Initial = [2/1,1/2,1/3,3/3,3/2,3/1,2/2,1/1,2/3] ?
|
||||
|
||||
yes
|
||||
|
||||
|
||||
% turn off performance monitor
|
||||
|
||||
| ?- performance::stop.
|
103
Logtalk/examples/searching/best_first1.lgt
Normal file
103
Logtalk/examples/searching/best_first1.lgt
Normal file
@@ -0,0 +1,103 @@
|
||||
|
||||
:- object(best_first(Threshold),
|
||||
instantiates(heuristic_search(Threshold))).
|
||||
|
||||
|
||||
:- info([
|
||||
version is 1.0,
|
||||
authors is 'Paulo Moura',
|
||||
date is 1998/3/23,
|
||||
comment is 'Best first heuristic state space search strategy.',
|
||||
parnames is ['Threshold']]).
|
||||
|
||||
|
||||
:- uses(list).
|
||||
|
||||
:- private(expand/8).
|
||||
:- private(succlist/5).
|
||||
:- private(bestf/3).
|
||||
:- private(continue/9).
|
||||
:- private(f/2).
|
||||
:- private(insert/4).
|
||||
|
||||
|
||||
search(Space, State, Threshold, Solution, Cost) :-
|
||||
expand([], l(State, 0/0), Threshold, _, yes, Path, Space, Cost),
|
||||
list::reverse(Path, Solution).
|
||||
|
||||
|
||||
expand(Path, l(State,Cost/_), _, _, yes, [State|Path], Space, Cost) :-
|
||||
Space::goal_state(State).
|
||||
|
||||
expand(Path, l(State,F/G), Threshold, Tree, Solved, Solution, Space, Cost) :-
|
||||
F =< Threshold,
|
||||
(bagof(Next/Cost,
|
||||
(Space::next_state(State, Next, Cost), \+ list::member(Next, Path)),
|
||||
Successors) ->
|
||||
succlist(G, Successors, Trees, Threshold, Space),
|
||||
bestf(Trees, F2, Threshold),
|
||||
expand(Path, t(State, F2/G, Trees), Threshold, Tree, Solved, Solution, Space, Cost)
|
||||
;
|
||||
Solved = never).
|
||||
|
||||
expand(Path, t(State, F/G,[Tree| Trees]), Threshold, Tree3, Solved, Solution, Space, Cost) :-
|
||||
F =< Threshold,
|
||||
bestf(Trees, Threshold2, Threshold),
|
||||
expand([State|Path], Tree, Threshold2, Tree2, Solved2, Solution, Space, Cost),
|
||||
continue(Path, t(State, F/G, [Tree2| Trees]), Threshold, Tree3, Solved2, Solved, Solution, Space, Cost).
|
||||
|
||||
|
||||
expand(_, t(_, _, []), _, _, never, _, _, _) :-
|
||||
!.
|
||||
|
||||
expand(_, Tree, Threshold, Tree, no, _, _, _) :-
|
||||
f(Tree, F),
|
||||
F > Threshold.
|
||||
|
||||
|
||||
continue(_, _, _, _, yes, yes, _, _, _).
|
||||
|
||||
continue(Path, t(State, _/G, [Tree| Trees]), Threshold, Tree2, no, Solved, Solution, Space, Cost) :-
|
||||
insert(Tree, Trees, NewTrees, Threshold),
|
||||
bestf(NewTrees, F, Threshold),
|
||||
expand(Path, t(State, F/G, NewTrees), Threshold, Tree2, Solved, Solution, Space, Cost).
|
||||
|
||||
continue(Path,t(State, _/G, [_| Trees]), Threshold, Tree2, never, Solved, Solution, Space, Cost) :-
|
||||
bestf(Trees, F, Threshold),
|
||||
expand(Path, t(State, F/G, Trees), Threshold, Tree2, Solved, Solution, Space, Cost).
|
||||
|
||||
|
||||
succlist(_, [], [], _, _).
|
||||
|
||||
succlist(G0, [State/Cost| Rest], Trees, Threshold, Space) :-
|
||||
G is G0 + Cost,
|
||||
Space::heuristic(State, H),
|
||||
F is G + H,
|
||||
succlist(G0, Rest, Trees2, Threshold, Space),
|
||||
insert(l(State, F/G), Trees2, Trees, Threshold).
|
||||
|
||||
|
||||
insert(Tree, [], [Tree], _) :-
|
||||
!.
|
||||
|
||||
insert(Tree, Trees, [Tree| Trees], Threshold) :-
|
||||
f(Tree, F),
|
||||
bestf(Trees, F2, Threshold),
|
||||
F =< F2,
|
||||
!.
|
||||
|
||||
insert(Tree, [Tree1| Trees], [Tree1| Trees1], Threshold) :-
|
||||
insert(Tree, Trees, Trees1, Threshold).
|
||||
|
||||
|
||||
f(l(_, F/_), F).
|
||||
f(t(_, F/_, _), F).
|
||||
|
||||
|
||||
bestf([Tree| _], F, _) :-
|
||||
f(Tree, F).
|
||||
|
||||
bestf([], Threshold, Threshold).
|
||||
|
||||
|
||||
:- end_object.
|
43
Logtalk/examples/searching/blind_search1.lgt
Normal file
43
Logtalk/examples/searching/blind_search1.lgt
Normal file
@@ -0,0 +1,43 @@
|
||||
|
||||
:- object(blind_search(_),
|
||||
instantiates(class),
|
||||
specializes(search_strategy)).
|
||||
|
||||
|
||||
:- info([
|
||||
version is 1.0,
|
||||
authors is 'Paulo Moura',
|
||||
date is 1998/3/23,
|
||||
comment is 'Blind search state space strategies.',
|
||||
parnames is ['Bound']]).
|
||||
|
||||
|
||||
|
||||
:- public(bound/1).
|
||||
|
||||
:- mode(bound(?integer), zero_or_one).
|
||||
|
||||
:- info(bound/1,
|
||||
[comment is 'Search depth bound.',
|
||||
argnames is ['Bound']]).
|
||||
|
||||
|
||||
:- protected(search/4).
|
||||
|
||||
:- mode(search(+object, +nonvar, +integer, -list), zero_or_more).
|
||||
|
||||
:- info(search/4,
|
||||
[comment is 'State space search solution.',
|
||||
argnames is ['Space', 'State', 'Bound', 'Path']]).
|
||||
|
||||
|
||||
bound(Bound) :-
|
||||
parameter(1, Bound).
|
||||
|
||||
|
||||
solve(Space, State, Path) :-
|
||||
::bound(Bound),
|
||||
::search(Space, State, Bound, Path).
|
||||
|
||||
|
||||
:- end_object.
|
61
Logtalk/examples/searching/breadth_first1.lgt
Normal file
61
Logtalk/examples/searching/breadth_first1.lgt
Normal file
@@ -0,0 +1,61 @@
|
||||
|
||||
:- object(breadth_first(Bound),
|
||||
instantiates(blind_search(Bound))).
|
||||
|
||||
|
||||
:- info([
|
||||
version is 1.0,
|
||||
authors is 'Paulo Moura',
|
||||
date is 1998/3/23,
|
||||
comment is 'Breadth first state space search strategy.',
|
||||
parnames is ['Bound']]).
|
||||
|
||||
|
||||
:- calls(state_space).
|
||||
|
||||
|
||||
:- uses(list).
|
||||
|
||||
|
||||
search(Space, State, Bound, Solution) :-
|
||||
breadt(Space, l(State), Bound, Path),
|
||||
list::reverse(Path, Solution).
|
||||
|
||||
|
||||
breadt(Space, Tree, Bound, Solution) :-
|
||||
expand([], Tree, Tree2, Solved, Solution, Space, Bound),
|
||||
(Solved ->
|
||||
true
|
||||
;
|
||||
breadt(Space, Tree2, Bound, Solution)).
|
||||
|
||||
|
||||
expand(Path, l(State), _, true, [State| Path], Space, _) :-
|
||||
Space::goal_state(State).
|
||||
|
||||
expand(Path, l(State), t(State, Subs), fail, _, Space, Bound) :-
|
||||
Bound > 0,
|
||||
bagof(l(Next),
|
||||
(Space::next_state(State, Next),
|
||||
\+ list::member(Next, [State| Path])),
|
||||
Subs).
|
||||
|
||||
expand(Path, t(State,Subs), t(State, Subs2), Solved, Solution, Space, Bound) :-
|
||||
expandall([State| Path], Subs, [], Subs2, Solved, Solution, Space, Bound).
|
||||
|
||||
|
||||
expandall(_, [], [Tree| Trees], [Tree| Trees], fail, _, _, _).
|
||||
|
||||
expandall(Path, [Tree| Trees], Trees2, Subs2, Solved, Solution, Space, Bound) :-
|
||||
Bound > 0,
|
||||
Bound2 is Bound -1,
|
||||
expand(Path, Tree, Tree2, Solved2, Solution, Space, Bound2),
|
||||
(Solved2 ->
|
||||
Solved = true
|
||||
;
|
||||
expandall(Path, Trees, [Tree2| Trees2], Subs2, Solved, Solution, Space, Bound))
|
||||
;
|
||||
expandall(Path, Trees, Trees2, Subs2, Solved, Solution, Space, Bound).
|
||||
|
||||
|
||||
:- end_object.
|
33
Logtalk/examples/searching/depth_first1.lgt
Normal file
33
Logtalk/examples/searching/depth_first1.lgt
Normal file
@@ -0,0 +1,33 @@
|
||||
|
||||
:- object(depth_first(Bound),
|
||||
instantiates(blind_search(Bound))).
|
||||
|
||||
|
||||
:- info([
|
||||
version is 1.0,
|
||||
authors is 'Paulo Moura',
|
||||
date is 1998/3/23,
|
||||
comment is 'Depth first state space search strategy.',
|
||||
parnames is ['Bound']]).
|
||||
|
||||
|
||||
:- uses(list).
|
||||
|
||||
|
||||
search(Space, State, Bound, Solution) :-
|
||||
depth(Space, State, Bound, [], Path),
|
||||
list::reverse(Path, Solution).
|
||||
|
||||
|
||||
depth(Space, State, _, Path, [State| Path]) :-
|
||||
Space::goal_state(State).
|
||||
|
||||
depth(Space, State, Bound, Path, Solution) :-
|
||||
Bound > 0,
|
||||
Space::next_state(State, Next),
|
||||
\+ list::member(Next, [State| Path]),
|
||||
Bound2 is Bound - 1,
|
||||
depth(Space, Next, Bound2, [State| Path], Solution).
|
||||
|
||||
|
||||
:- end_object.
|
105
Logtalk/examples/searching/eight_puzzle.lgt
Normal file
105
Logtalk/examples/searching/eight_puzzle.lgt
Normal file
@@ -0,0 +1,105 @@
|
||||
|
||||
:- object(eight_puzzle,
|
||||
instantiates(heuristic_state_space)).
|
||||
|
||||
|
||||
:- info([
|
||||
version is 1.0,
|
||||
authors is 'Paulo Moura',
|
||||
date is 1998/3/23,
|
||||
comment is 'Eight puzzle heuristic state space search problem.']).
|
||||
|
||||
|
||||
:- uses(list).
|
||||
|
||||
|
||||
initial_state(four_steps, [2/2,1/3,3/2,2/3,3/3,3/1,2/1,1/1,1/2]).
|
||||
|
||||
initial_state(five_steps, [2/1,1/2,1/3,3/3,3/2,3/1,2/2,1/1,2/3]).
|
||||
|
||||
initial_state(eighteen_steps, [2/2,2/3,1/3,3/1,1/2,2/1,3/3,1/1,3/2]).
|
||||
|
||||
|
||||
goal_state(goal, [2/2,1/3,2/3,3/3,3/2,3/1,2/1,1/1,1/2]).
|
||||
|
||||
|
||||
print_state([S0,S1,S2,S3,S4,S5,S6,S7,S8]) :-
|
||||
list::member(Y, [3, 2, 1]),
|
||||
nl,
|
||||
list::member(X, [1, 2, 3]),
|
||||
list::member(Tile-X/Y, [' '-S0,1-S1,2-S2,3-S3,4-S4,5-S5,6-S6,7-S7,8-S8]),
|
||||
write(Tile),
|
||||
fail.
|
||||
|
||||
print_state(_) :-
|
||||
nl.
|
||||
|
||||
|
||||
next_state([Empty| L], [Tile| L2], 1) :-
|
||||
swap(Empty, Tile, L, L2).
|
||||
|
||||
|
||||
swap(Empty, Tile, [Tile| L], [Empty| L]) :-
|
||||
dist(Empty, Tile, 1).
|
||||
|
||||
swap(Empty, Tile, [Tile2| L], [Tile2| L2]) :-
|
||||
swap(Empty, Tile, L, L2).
|
||||
|
||||
|
||||
dist(X/Y, X2/Y2, D) :-
|
||||
abs_diff(X, X2, Dx),
|
||||
abs_diff(Y, Y2, Dy),
|
||||
D is Dx + Dy.
|
||||
|
||||
|
||||
abs_diff(A, B, D) :-
|
||||
A > B ->
|
||||
D is A - B
|
||||
;
|
||||
D is B - A.
|
||||
|
||||
|
||||
heuristic([_| L], H) :-
|
||||
goal_state(_, [_| G]),
|
||||
totdist(L, G, 0, D),
|
||||
seq(L, S),
|
||||
H is D + 3*S.
|
||||
|
||||
|
||||
totdist([], [], D, D).
|
||||
|
||||
totdist([T| L], [T2| L2], Acc, D) :-
|
||||
dist(T, T2, D1),
|
||||
Acc2 is Acc + D1,
|
||||
totdist(L, L2, Acc2, D).
|
||||
|
||||
|
||||
seq([First| L], S) :-
|
||||
seq([First| L], First, 0, S).
|
||||
|
||||
|
||||
seq([T1, T2| L], First, Acc, S) :-
|
||||
score(T1, T2, S1),
|
||||
Acc2 is Acc + S1,
|
||||
seq([T2| L], First, Acc2, S).
|
||||
|
||||
seq([Last], First, Acc, S) :-
|
||||
score(Last, First, Score),
|
||||
S is Acc + Score.
|
||||
|
||||
|
||||
score(2/2, _, 1) :- !.
|
||||
|
||||
score(1/3, 2/3, 0) :- !.
|
||||
score(2/3, 3/3, 0) :- !.
|
||||
score(3/3, 3/2, 0) :- !.
|
||||
score(3/2, 3/1, 0) :- !.
|
||||
score(3/1, 2/1, 0) :- !.
|
||||
score(2/1, 1/1, 0) :- !.
|
||||
score(1/1, 1/2, 0) :- !.
|
||||
score(1/2, 1/3, 0) :- !.
|
||||
|
||||
score(_, _, 2) :- !.
|
||||
|
||||
|
||||
:- end_object.
|
63
Logtalk/examples/searching/farmer.lgt
Normal file
63
Logtalk/examples/searching/farmer.lgt
Normal file
@@ -0,0 +1,63 @@
|
||||
|
||||
:- object(farmer,
|
||||
instantiates(state_space)).
|
||||
|
||||
|
||||
:- info([
|
||||
version is 1.0,
|
||||
authors is 'Paulo Moura',
|
||||
date is 1998/3/23,
|
||||
comment is 'Farmer, cabbage, goat, and wolf state space search problem.']).
|
||||
|
||||
|
||||
initial_state(start, (north, north, north, north)).
|
||||
|
||||
|
||||
goal_state(end, (south, south, south, south)).
|
||||
|
||||
|
||||
next_state((Cabbage, Goat, Wolf, Farmer), (FCabbage, Goat, Wolf, FFarmer)) :-
|
||||
same_side(Farmer, Cabbage),
|
||||
\+ same_side(Goat, Wolf),
|
||||
flip(Farmer, FFarmer),
|
||||
flip(Cabbage, FCabbage).
|
||||
|
||||
next_state((Cabbage, Goat, Wolf, Farmer), (Cabbage, FGloat, Wolf, FFarmer)) :-
|
||||
same_side(Farmer, Goat),
|
||||
flip(Farmer, FFarmer),
|
||||
flip(Goat, FGloat).
|
||||
|
||||
next_state((Cabbage, Goat, Wolf, Farmer), (Cabbage, Goat, FWolf, FFarmer)) :-
|
||||
same_side(Farmer, Wolf),
|
||||
\+ same_side(Cabbage, Goat),
|
||||
flip(Farmer, FFarmer),
|
||||
flip(Wolf, FWolf).
|
||||
|
||||
next_state((Cabbage, Goat, Wolf, Farmer), (Cabbage, Goat, Wolf, FFarmer)) :-
|
||||
\+ same_side(Cabbage, Goat),
|
||||
\+ same_side(Goat, Wolf),
|
||||
flip(Farmer, FFarmer).
|
||||
|
||||
|
||||
flip(north, south).
|
||||
|
||||
flip(south, north).
|
||||
|
||||
|
||||
same_side(north, north).
|
||||
|
||||
same_side(south, south).
|
||||
|
||||
|
||||
print_state((Cabbage, Goat, Wolf, Farmer)) :-
|
||||
(Cabbage = north -> write(c); write('_')),
|
||||
(Goat = north -> write(g); write('_')),
|
||||
(Wolf = north -> write(w); write('_')),
|
||||
(Farmer = north -> write('f.<__>.........._'); write('_..........<__>.f')),
|
||||
(Cabbage = north -> write('_'); write(c)),
|
||||
(Goat = north -> write('_'); write(g)),
|
||||
(Wolf = north -> write('_'); write(w)),
|
||||
nl.
|
||||
|
||||
|
||||
:- end_object.
|
55
Logtalk/examples/searching/heuristic_search1.lgt
Normal file
55
Logtalk/examples/searching/heuristic_search1.lgt
Normal file
@@ -0,0 +1,55 @@
|
||||
|
||||
:- object(heuristic_search(_),
|
||||
instantiates(class),
|
||||
specializes(search_strategy)).
|
||||
|
||||
|
||||
:- info([
|
||||
version is 1.0,
|
||||
authors is 'Paulo Moura',
|
||||
date is 1998/3/23,
|
||||
comment is 'Heuristic state space search strategies.',
|
||||
parnames is ['Threshold']]).
|
||||
|
||||
|
||||
:- public(threshold/1).
|
||||
|
||||
:- mode(threshold(?number), one).
|
||||
|
||||
:- info(threshold/1,
|
||||
[comment is 'Search cost threshold.',
|
||||
argnames is ['Threshold']]).
|
||||
|
||||
|
||||
:- public(solve/4).
|
||||
|
||||
:- mode(solve(+object, +nonvar, -list, -number), zero_or_more).
|
||||
|
||||
:- info(solve/4,
|
||||
[comment is 'State space search solution.',
|
||||
argnames is ['Space', 'State', 'Path', 'Cost']]).
|
||||
|
||||
|
||||
:- protected(search/5).
|
||||
|
||||
:- mode(search(+object, +nonvar, +number, -list, -number), zero_or_more).
|
||||
|
||||
:- info(search/5,
|
||||
[comment is 'State space search solution.',
|
||||
argnames is ['Space', 'State', 'Threshold', 'Path', 'Cost']]).
|
||||
|
||||
|
||||
solve(Space, State, Path) :-
|
||||
::solve(Space, State, Path, _).
|
||||
|
||||
|
||||
solve(Space, State, Path, Cost) :-
|
||||
::threshold(Threshold),
|
||||
::search(Space, State, Threshold, Path, Cost).
|
||||
|
||||
|
||||
threshold(Threshold) :-
|
||||
parameter(1, Threshold).
|
||||
|
||||
|
||||
:- end_object.
|
36
Logtalk/examples/searching/heuristic_state_space.lgt
Normal file
36
Logtalk/examples/searching/heuristic_state_space.lgt
Normal file
@@ -0,0 +1,36 @@
|
||||
|
||||
:- object(heuristic_state_space,
|
||||
instantiates(class),
|
||||
specializes(state_space)).
|
||||
|
||||
|
||||
:- info([
|
||||
version is 1.0,
|
||||
authors is 'Paulo Moura',
|
||||
date is 1998/3/23,
|
||||
comment is 'Heuristic state space.']).
|
||||
|
||||
|
||||
:- public(next_state/3).
|
||||
|
||||
:- mode(next_state(+nonvar, -nonvar, -number), zero_or_more).
|
||||
|
||||
:- info(next_state/2,
|
||||
[comment is 'Generates a state sucessor.',
|
||||
argnames is ['State', 'Next', 'Cost']]).
|
||||
|
||||
|
||||
:- public(heuristic/2).
|
||||
|
||||
:- mode(heuristic(+nonvar, -number), one).
|
||||
|
||||
:- info(heuristic/2,
|
||||
[comment is 'Estimates state distance to a goal state.',
|
||||
argnames is ['State', 'Estimate']]).
|
||||
|
||||
|
||||
next_state(Prev, Next) :-
|
||||
::next_state(Prev, Next, _).
|
||||
|
||||
|
||||
:- end_object.
|
42
Logtalk/examples/searching/hill_climbing1.lgt
Normal file
42
Logtalk/examples/searching/hill_climbing1.lgt
Normal file
@@ -0,0 +1,42 @@
|
||||
|
||||
:- object(hill_climbing(Threshold),
|
||||
instantiates(heuristic_search(Threshold))).
|
||||
|
||||
|
||||
:- info([
|
||||
version is 1.0,
|
||||
authors is 'Paulo Moura',
|
||||
date is 1998/3/23,
|
||||
comment is 'Hill climbing heuristic state space search strategy.',
|
||||
parnames is ['Threshold']]).
|
||||
|
||||
|
||||
:- uses(list).
|
||||
|
||||
:- private(hill/7).
|
||||
|
||||
|
||||
search(Space, State, Threshold, Solution, Cost) :-
|
||||
hill(Space, State, Threshold, [], Path, 0, Cost),
|
||||
list::reverse(Path, Solution).
|
||||
|
||||
|
||||
hill(Space, State, _, Path, [State| Path], Cost, Cost) :-
|
||||
Space::goal_state(State).
|
||||
|
||||
hill(Space, State, Threshold, Path, Solution, SoFar, Total) :-
|
||||
SoFar < Threshold,
|
||||
findall(
|
||||
(Estimate, Cost, Next),
|
||||
(Space::next_state(State, Next, Cost),
|
||||
\+ list::member(Next, [State| Path]),
|
||||
Space::heuristic(Next, Guess),
|
||||
Estimate is Guess + Cost),
|
||||
States),
|
||||
list::sort(States, SortedStates),
|
||||
list::member((_, Cost, Next), SortedStates),
|
||||
SoFar2 is SoFar + Cost,
|
||||
hill(Space, Next, Threshold, [State| Path], Solution, SoFar2, Total).
|
||||
|
||||
|
||||
:- end_object.
|
85
Logtalk/examples/searching/miss_cann.lgt
Normal file
85
Logtalk/examples/searching/miss_cann.lgt
Normal file
@@ -0,0 +1,85 @@
|
||||
|
||||
:- object(miss_cann,
|
||||
instantiates(heuristic_state_space)).
|
||||
|
||||
|
||||
:- info([
|
||||
version is 1.1,
|
||||
authors is 'Paulo Moura',
|
||||
date is 2000/11/21,
|
||||
comment is 'Missionaries and cannibals heuristic state space search problem.']).
|
||||
|
||||
|
||||
:- uses(loop).
|
||||
|
||||
|
||||
initial_state(start, ((3,3), left, (0,0))).
|
||||
|
||||
|
||||
goal_state(end, ((0,0), right, (3,3))).
|
||||
|
||||
|
||||
print_state(((Me,Ce), B, (Md,Cd))) :-
|
||||
loop::forto(1, Me, write('M')),
|
||||
loop::forto(1, Ce, write('C')),
|
||||
(B = left ->
|
||||
write('.<__>..........')
|
||||
;
|
||||
write('..........<__>.')),
|
||||
loop::forto(1, Md, write('M')),
|
||||
loop::forto(1, Cd, write('C')),
|
||||
nl.
|
||||
|
||||
|
||||
next_state(((Me,Ce),left,(Md,Cd)), ((Me2,Ce2),right,(Md2,Cd2)), 1) :- %mm
|
||||
Me >= 2,
|
||||
once((Me - 2 =:= 0; Me - 2 >= Ce)),
|
||||
Cd =< 2,
|
||||
Me2 is Me - 2,
|
||||
Ce2 is Ce,
|
||||
Md2 is Md + 2,
|
||||
Cd2 is Cd.
|
||||
|
||||
next_state(((Me,Ce),left,(Md,Cd)), ((Me2,Ce2),right,(Md2,Cd2)), 2) :- %m
|
||||
Me >= 1,
|
||||
once((Me - 1 =:= 0; Me - 1 >= Ce)),
|
||||
Cd =< 1,
|
||||
Me2 is Me - 1,
|
||||
Ce2 is Ce,
|
||||
Md2 is Md + 1,
|
||||
Cd2 is Cd.
|
||||
|
||||
next_state(((Me,Ce),left,(Md,Cd)), ((Me2,Ce2),right,(Md2,Cd2)), 1) :- %cc
|
||||
Ce >= 2,
|
||||
once((Md >= Cd + 2; Md =:= 0)),
|
||||
Me2 is Me,
|
||||
Ce2 is Ce - 2,
|
||||
Md2 is Md,
|
||||
Cd2 is Cd + 2.
|
||||
|
||||
next_state(((Me,Ce),left,(Md,Cd)), ((Me2,Ce2),right,(Md2,Cd2)), 2) :- %c
|
||||
Ce >= 1,
|
||||
once((Md >= Cd + 1; Md =:= 0)),
|
||||
Me2 is Me,
|
||||
Ce2 is Ce - 1,
|
||||
Md2 is Md,
|
||||
Cd2 is Cd + 1.
|
||||
|
||||
next_state(((Me,Ce),left,(Md,Cd)), ((Me2,Ce2),right,(Md2,Cd2)), 1) :- %mc
|
||||
Me >= 1,
|
||||
Ce >= 1,
|
||||
Md >= Cd,
|
||||
Me2 is Me - 1,
|
||||
Ce2 is Ce - 1,
|
||||
Md2 is Md + 1,
|
||||
Cd2 is Cd + 1.
|
||||
|
||||
next_state(((Me,Ce),right,(Md,Cd)), ((Me2,Ce2),left,(Md2,Cd2)), Cost) :-
|
||||
next_state(((Md,Cd),left,(Me,Ce)), ((Md2,Cd2),right,(Me2,Ce2)), Cost).
|
||||
|
||||
|
||||
heuristic(((_, _), _, (Md, Cd)), Cost) :-
|
||||
Cost is 6 - (Md + Cd).
|
||||
|
||||
|
||||
:- end_object.
|
163
Logtalk/examples/searching/performance.lgt
Normal file
163
Logtalk/examples/searching/performance.lgt
Normal file
@@ -0,0 +1,163 @@
|
||||
|
||||
:- object(performance,
|
||||
implements(event_handlersp)).
|
||||
|
||||
|
||||
:- info([
|
||||
version is 1.0,
|
||||
authors is 'Paulo Moura',
|
||||
date is 1998/3/23,
|
||||
comment is 'Performance monitor for state space searches.']).
|
||||
|
||||
|
||||
:- uses(event_registry).
|
||||
:- uses(before_event_registry).
|
||||
:- uses(after_event_registry).
|
||||
:- uses(list).
|
||||
:- uses(numberlist).
|
||||
:- uses(time).
|
||||
|
||||
|
||||
:- private(transitions/3).
|
||||
:- dynamic(transitions/3).
|
||||
:- mode(transitions(?state, ?state, ?integer), zero_or_more).
|
||||
|
||||
:- private(solution_length/1).
|
||||
:- dynamic(solution_length/1).
|
||||
:- mode(solution_length(?integer), zero_or_one).
|
||||
|
||||
:- private(start_time/1).
|
||||
:- dynamic(start_time/1).
|
||||
:- mode(start_time(-number), zero_or_one).
|
||||
|
||||
:- private(end_time/1).
|
||||
:- dynamic(end_time/1).
|
||||
:- mode(end_time(-number), zero_or_one).
|
||||
|
||||
:- public(time/1).
|
||||
:- mode(time(-number), zero_or_one).
|
||||
|
||||
:- public(transitions/1).
|
||||
:- mode(transitions(-number), zero_or_one).
|
||||
|
||||
:- public(branching/3).
|
||||
:- mode(branching(-integer, -float, -integer), zero_or_one).
|
||||
|
||||
:- public(report/0).
|
||||
:- mode(report, zero_or_one).
|
||||
|
||||
:- public(init/0).
|
||||
:- mode(init, one).
|
||||
|
||||
:- public(stop/0).
|
||||
:- mode(stop, one).
|
||||
|
||||
|
||||
report :-
|
||||
::solution_length(Length),
|
||||
::transitions(Number),
|
||||
Ratio is Length / Number,
|
||||
::branching(Minimum, Average, Maximum),
|
||||
::time(Time),
|
||||
write('solution length: '), write(Length), nl,
|
||||
write('state transitions: '), write(Number), nl,
|
||||
write('ratio solution length / state transitions: '), write(Ratio), nl,
|
||||
write('minimum branching degree: '), write(Minimum), nl,
|
||||
write('average branching degree: '), write(Average), nl,
|
||||
write('maximum branching degree: '), write(Maximum), nl,
|
||||
write('time: '), write(Time), nl,
|
||||
!.
|
||||
|
||||
|
||||
transitions(Number) :-
|
||||
findall(N, ::transitions(_, _, N), List),
|
||||
numberlist::sum(List, Number).
|
||||
|
||||
|
||||
time(Time) :-
|
||||
::start_time(Start),
|
||||
::end_time(End),
|
||||
Time is End - Start.
|
||||
|
||||
|
||||
branching(Minimum, Average, Maximum) :-
|
||||
findall(
|
||||
Length,
|
||||
(::transitions(State1, _, _),
|
||||
findall(State2, ::transitions(State1, State2, _), States2),
|
||||
list::length(States2, Length)),
|
||||
Lengths),
|
||||
list::sort(Lengths, SortedLengths),
|
||||
SortedLengths = [Minimum| _],
|
||||
list::reverse(SortedLengths, [Maximum| _]),
|
||||
numberlist::sum(Lengths, Sum),
|
||||
list::length(Lengths, Length),
|
||||
Average is Sum / Length.
|
||||
|
||||
|
||||
init :-
|
||||
self(Self),
|
||||
event_registry::set_monitor(_, solve(_, _, _), _, Self),
|
||||
after_event_registry::set_monitor(_, next_state(_, _), _, Self),
|
||||
event_registry::set_monitor(_, solve(_, _, _, _), _, Self),
|
||||
after_event_registry::set_monitor(_, next_state(_, _, _), _, Self),
|
||||
::retractall(transitions(_, _, _)),
|
||||
::retractall(start_time(_)),
|
||||
::retractall(end_time(_)),
|
||||
::retractall(solution_length(_)).
|
||||
|
||||
|
||||
stop :-
|
||||
self(Self),
|
||||
before_event_registry::del_monitors(_, _, _, Self),
|
||||
after_event_registry::del_monitors(_, _, _, Self).
|
||||
|
||||
|
||||
before(_, solve(_, _, _), _) :-
|
||||
!,
|
||||
time::cpu_time(Time),
|
||||
::assertz(start_time(Time)).
|
||||
|
||||
before(_, solve(_, _, _, _), _) :-
|
||||
!,
|
||||
time::cpu_time(Time),
|
||||
::assertz(start_time(Time)).
|
||||
|
||||
|
||||
after(_, next_state(S1, S2), _) :-
|
||||
!,
|
||||
(::transitions(S1, S2, N) ->
|
||||
N2 is N + 1
|
||||
;
|
||||
N2 is 1),
|
||||
::retractall(transitions(S1, S2, _)),
|
||||
::assertz(transitions(S1, S2, N2)).
|
||||
|
||||
after(_, next_state(S1, S2, _), _) :-
|
||||
!,
|
||||
(::transitions(S1, S2, N) ->
|
||||
N2 is N + 1
|
||||
;
|
||||
N2 is 1),
|
||||
::retractall(transitions(S1, S2, _)),
|
||||
::assertz(transitions(S1, S2, N2)).
|
||||
|
||||
after(_, solve(_, _, Solution), _) :-
|
||||
!,
|
||||
time::cpu_time(Time),
|
||||
::assertz(end_time(Time)),
|
||||
list::length(Solution, Length),
|
||||
::retractall(solution_length(_)),
|
||||
::asserta(solution_length(Length)).
|
||||
|
||||
after(_, solve(_, _, Solution, _), _) :-
|
||||
!,
|
||||
time::cpu_time(Time),
|
||||
::assertz(end_time(Time)),
|
||||
list::length(Solution, Length),
|
||||
::retractall(solution_length(_)),
|
||||
::asserta(solution_length(Length)).
|
||||
|
||||
|
||||
:- end_object.
|
||||
|
23
Logtalk/examples/searching/search_strategy.lgt
Normal file
23
Logtalk/examples/searching/search_strategy.lgt
Normal file
@@ -0,0 +1,23 @@
|
||||
|
||||
:- object(search_strategy,
|
||||
instantiates(abstract_class),
|
||||
specializes(object)).
|
||||
|
||||
|
||||
:- info([
|
||||
version is 1.0,
|
||||
authors is 'Paulo Moura',
|
||||
date is 1998/3/23,
|
||||
comment is 'State space search strategies.']).
|
||||
|
||||
|
||||
:- public(solve/3).
|
||||
|
||||
:- mode(solve(+object, +nonvar, -list), zero_or_more).
|
||||
|
||||
:- info(solve/3,
|
||||
[comment is 'State space search solution.',
|
||||
argnames is ['Space', 'State', 'Path']]).
|
||||
|
||||
|
||||
:- end_object.
|
17
Logtalk/examples/searching/searching.loader
Normal file
17
Logtalk/examples/searching/searching.loader
Normal file
@@ -0,0 +1,17 @@
|
||||
|
||||
:- initialization(
|
||||
logtalk_load([
|
||||
best_first1,
|
||||
blind_search1,
|
||||
breadth_first1,
|
||||
depth_first1,
|
||||
eight_puzzle,
|
||||
farmer,
|
||||
heuristic_search1,
|
||||
heuristic_state_space,
|
||||
hill_climbing1,
|
||||
miss_cann,
|
||||
performance,
|
||||
search_strategy,
|
||||
state_space,
|
||||
water_jug])).
|
96
Logtalk/examples/searching/state_space.lgt
Normal file
96
Logtalk/examples/searching/state_space.lgt
Normal file
@@ -0,0 +1,96 @@
|
||||
|
||||
:- object(state_space,
|
||||
instantiates(class),
|
||||
specializes(object)).
|
||||
|
||||
|
||||
:- info([
|
||||
version is 1.0,
|
||||
authors is 'Paulo Moura',
|
||||
date is 1998/3/23,
|
||||
comment is 'State space description predicates.']).
|
||||
|
||||
|
||||
:- public(initial_state/1).
|
||||
|
||||
:- mode(initial_state(?nonvar), one_or_more).
|
||||
|
||||
:- info(initial_state/1,
|
||||
[comment is 'Initial state.',
|
||||
argnames is ['State']]).
|
||||
|
||||
|
||||
:- public(initial_state/2).
|
||||
|
||||
:- mode(initial_state(?atom, ?nonvar), zero_or_more).
|
||||
|
||||
:- info(initial_state/2,
|
||||
[comment is 'Named initial state.',
|
||||
argnames is ['Name', 'State']]).
|
||||
|
||||
|
||||
:- public(next_state/2).
|
||||
|
||||
:- mode(next_state(+nonvar, -nonvar), zero_or_more).
|
||||
|
||||
:- info(next_state/2,
|
||||
[comment is 'Generates a state sucessor.',
|
||||
argnames is ['State', 'Next']]).
|
||||
|
||||
|
||||
:- public(goal_state/1).
|
||||
|
||||
:- mode(goal_state(?nonvar), one_or_more).
|
||||
|
||||
:- info(goal_state/1,
|
||||
[comment is 'Goal state.',
|
||||
argnames is ['State']]).
|
||||
|
||||
|
||||
:- public(goal_state/2).
|
||||
|
||||
:- mode(goal_state(?atom, ?nonvar), zero_or_more).
|
||||
|
||||
:- info(goal_state/2,
|
||||
[comment is 'Named goal state.',
|
||||
argnames is ['Name', 'State']]).
|
||||
|
||||
|
||||
:- public(print_state/1).
|
||||
|
||||
:- mode(print_state(+nonvar), one).
|
||||
|
||||
:- info(print_state/1,
|
||||
[comment is 'Pretty print state.',
|
||||
argnames is ['State']]).
|
||||
|
||||
|
||||
:- public(print_path/1).
|
||||
|
||||
:- mode(print_path(+list), one).
|
||||
|
||||
:- info(print_path/1,
|
||||
[comment is 'Pretty print a path (list of states).',
|
||||
argnames is ['Path']]).
|
||||
|
||||
|
||||
initial_state(State) :-
|
||||
::initial_state(_, State).
|
||||
|
||||
|
||||
goal_state(State) :-
|
||||
::goal_state(_, State).
|
||||
|
||||
|
||||
print_state(State) :-
|
||||
writeq(State), nl.
|
||||
|
||||
|
||||
print_path([]).
|
||||
|
||||
print_path([State| States]) :-
|
||||
::print_state(State),
|
||||
print_path(States).
|
||||
|
||||
|
||||
:- end_object.
|
59
Logtalk/examples/searching/water_jug.lgt
Normal file
59
Logtalk/examples/searching/water_jug.lgt
Normal file
@@ -0,0 +1,59 @@
|
||||
|
||||
:- object(water_jug,
|
||||
instantiates(state_space)).
|
||||
|
||||
|
||||
:- info([
|
||||
version is 1.0,
|
||||
authors is 'Paulo Moura',
|
||||
date is 1998/3/23,
|
||||
comment is 'Water jug state space search problem.']).
|
||||
|
||||
|
||||
initial_state(start, (0, 0)).
|
||||
|
||||
|
||||
goal_state(end1, (2, 0)).
|
||||
|
||||
goal_state(end2, (0, 2)).
|
||||
|
||||
|
||||
next_state((X, Y), (4, Y)) :-
|
||||
X < 4.
|
||||
|
||||
next_state((X, Y),(X, 3)) :-
|
||||
Y < 3.
|
||||
|
||||
next_state((X, Y), (4, Z)) :-
|
||||
Y > 0, X < 4,
|
||||
Aux is X + Y, Aux >= 4,
|
||||
Z is Y - (4 - X).
|
||||
|
||||
next_state((X, Y), (Z, 3)) :-
|
||||
X > 0, Y < 3,
|
||||
Aux is X + Y, Aux >= 4,
|
||||
Z is X - (3 - Y).
|
||||
|
||||
next_state((X, Y),(Z, 0)) :-
|
||||
Y > 0,
|
||||
Aux is X + Y, Aux =< 4,
|
||||
Z is Y + X.
|
||||
|
||||
next_state((X, Y),(0, Z)) :-
|
||||
X > 0,
|
||||
Aux is X + Y, Aux =< 3,
|
||||
Z is Y + X.
|
||||
|
||||
next_state((X, Y), (0, Y)) :-
|
||||
X > 0.
|
||||
|
||||
next_state((X, Y), (X, 0)) :-
|
||||
Y > 0.
|
||||
|
||||
|
||||
print_state((X, Y)) :-
|
||||
write('4-gallon jug: '), write(X), nl,
|
||||
write('3-gallon jug: '), write(Y), nl, nl.
|
||||
|
||||
|
||||
:- end_object.
|
Reference in New Issue
Block a user