level 1
% State space definition to be used with IDA*
% Predicates needed are: s/2, f/2, goal/1
% To compute f, a node has also to include its search depth
% Problem-specific procedures for the 8-puzzle */
/* Current situation is represented as a list of positions
of the tiles, with first item in the list corresponding
to the empty square.
Example:
1 1 2 3 is represented by:
2 8 4 [2/2, 1/3, 2/3, 3/3, 3/2, 3/1, 2/1, 1/1]
3 7 6 5
1 2 3
'Empty' can move to any of its neighbours which means that
'empty' and its neighbour interchange their positions.
*/
% Specification for A*
s( [Empty|L], [T|L1], 1) :- % All arc-costs are 1
swap( Empty, T, L, L1). % Swap Empty and T in L giving L1
s( State0, State) :- % Ignore cost
s( State0, State, Cost).
swap( E, T, [T|L], [E|L]) :-
d( E, T, 1). % Manhattan dist. between E and T is 1
swap( E, T, [T1|L], [T1|L1]) :-
swap( E, T, L, L1).
d( X/Y, X1/Y1, D) :-
dif( X, X1, Dx),
dif( Y, Y1, Dy),
D is Dx + Dy.
dif( A, B, D) :-
D is A-B, D >= 0, !;
D is B-A.
% Heuristic estimate h is the sum of distances of each tile
% from its 'home' square plus 3 times 'sequencing' score
h( [Empty|L], H) :-
goal([Empty1|G]),
totdist( L, G, D),
seq( L, S),
H is D + 3*S.
totdist( [], [], 0).
totdist( [T|L], [T1|L1], D) :-
d( T, T1, D1),
totdist( L, L1, D2),
D is D1 + D2.
seq( [First|L], S) :-
seq( [First|L], First, S).
seq( [T1,T2|L], First, S) :-
score( T1, T2, S1),
seq( [T2|L], First, S2),
S is S1 + S2.
seq( [Last], First, S) :-
score( Last, First, S).
score( 2/2, _, 1) :- !. % Tile in centre scores 1
score( 1/3, 2/3, 0) :- !.
2010年04月08日 13点04分