Inconveniences with an "exception" prolog

0

You will see my code consists of placing a mosaic of 8 pieces (a list of lists) and a number N that indicates the number of steps you will take, and you have to show if with that number N you can reach the final state (state resolved) of the mosaic, if it is not equal gives false. example:

puzzle (X, N): Given an initial position X and a number of steps N, check if the minimum number of steps to get from X to the final state is equal to N. If it is not resolvable, you must return false.

mosaic: [[1,9,3], [5,2,6], [4,7,8]] resolved status is: [[1,2,3], [4,5,6 ], [7,8,9]] where nine is the vacuum, I found the code to interconnect with the algorithm A * that they asked me to use

and the function returns true in the case that it fulfills the correct case, example: puzzle ([[1,9,3], [5,2,6], [4,7,8]], 5 ) -True but if instead of 5 it is 3 that is not enough or 7 when it is too many, it gives me an exception and stays stuck.

my function puzzle use faltten and I use a function that replaces the 9 with the 0 since the code I got used the 0 as empty

GoalState([1,2,3,4,5,6,7,8,0]).

rompecabezas([X|T],N):- flatten([X|T],ListaAux), replace(9,0,ListaAux,ListaAux2), idsearch(ListaAux2,Val), Val == N.


replace(_, _, [], []).
replace(O, R, [O|T], [R|T2]) :- replace(O, R, T, T2).
replace(O, R, [H|T], [H|T2]) :- H \= O, replace(O, R, T, T2).



solution(ProblemName, Solution) :-
    retractall(problem(_,_)),
    [ProblemName],
    problem(I,G),
    solutionAux(problem(I,G), Solution).


% solutionAux(problem(+InitialState, +GoalState), -Solution)

solutionAux(problem(InitialState, GoalState), Solution) :-
    retractall(is_goal(_)),
    assert(is_goal(GoalState)),
    idsearch(InitialState, RevSolution),
    reverse(RevSolution, Solution).


% idsearch(N,P) is true if path P is a path found from node N
% using iterative deepening A* search
% Example query: idsearch(o103,P).
idsearch(N,P) :-
   h(N,HN),
   %%writeln(['Trying Depth bound: ',HN]),
   dbsearch([node(N,[],0)],HN,[node(N,[],0)],natural,Q), P is HN.

% dbsearch(F,DB,Q,How1,P) is true if a depth bound search from frontier F
% can find a path P of length >= DB.
% where Q is the initial frontier to (re)start from,
% How specifies whether the previous bound failed naturally or gives
% the minimum f-value for which the search failed.

% The frontier is a list of  node(Node,Path,PathLength)
%   where Node is a node, Path is the path found to Node,
%   PathLength is the length of the path.

%dbsearch(F,_,_,_,_) :-
%   writeln(['Frontier: ',F]),
%   fail.
dbsearch([],_,Q,NDB,S) :-
   number(NDB),
   writeln(['Trying Depth bound: ',NDB]),
   dbsearch(Q,NDB,Q,natural,S).
dbsearch([node(N,P,DB)|_],DB,_,_,[N|P]) :-
   is_goal(N).
dbsearch([node(N,P,PL)|F1],DB,Q,H,S) :-
   h(N,HN),
   HN+PL =< DB,
   neighbors(N,NewNs),
   subtract(NewNs, P, NNs),  % loop elimination
   add_paths_db(NNs,N,[N|P],PL,F1,F2),
   dbsearch(F2,DB,Q,H,S).
dbsearch([node(N,_,PL)|F1],DB,Q,H,S) :-
   h(N,HN),
   HN+PL > DB,
   min1(HN+PL,H,LUB),
   dbsearch(F1,DB,Q,LUB,S).

%   add_paths(NNs,N,Path,PL,F0,F1)
add_paths_db([],_,_,_,F,F).
add_paths_db([NN|R],N,Path,PL,F0,[node(NN,Path,PL1)|F1]) :-
   cost(N,NN,AC),
   PL1 is PL+AC,
   add_paths_db(R,N,Path,PL,F0,F1).

min1(E,natural,V) :- !, V is E.
min1(E,V,V) :- V =< E.
min1(E,V,V1) :- V > E, V1 is E.

% **************************************************
% writeln(L) is true if L is a list of items where each
% item is written on a separate line, followed by a newline.
writeln([]) :- nl.
writeln([H|T]) :- write(H), nl, writeln(T).


%% we are making all edge costs to be 1
%% if you want different edges to have
%% different costs you must comment this out
%% and include a cost predicate in the domain
%% file
cost(_,_,1).


%---------------------------------------------------%
neighbors(State, Neighbors) :-
    findall(Neighbor, successor(State, Neighbor), Neighbors).

successor(State, Neighbor) :-
    moveUp(State, Neighbor);
    moveDown(State, Neighbor);
    moveLeft(State, Neighbor);
    moveRight(State, Neighbor).

location(State, X, Y, Elem) :-
    nth0(Index, State, Elem),
    divmod(Index, 3, X, Y).

index(Index, X, Y) :-
    Index is 3 * X + Y.

swap(State, I1, I2, Final) :-
    same_length(State, Final),
    length(BeforeI1, I1),
    length(BeforeI2, I2),
    append(BeforeI1, [EI1|PastI1], State),
    append(BeforeI1, [EI2|PastI1], Temp),
    append(BeforeI2, [EI2|PastI2], Temp),
    append(BeforeI2, [EI1|PastI2], Final).

moveUp(State, Final) :-
    location(State, X, Y, 0),
    X > 0,
    Z is X - 1,
    index(Index, X, Y),
    index(NewIndex, Z, Y),
    swap(State, Index, NewIndex, Final).

moveDown(State, Final) :-
    location(State, X, Y, 0),
    X < 2,
    Z is X + 1,
    index(Index, X, Y),
    index(NewIndex, Z, Y),
    swap(State, Index, NewIndex, Final).

moveLeft(State, Final) :-
    location(State, X, Y, 0),
    Y > 0,
    Z is Y - 1,
    index(Index, X, Y),
    index(NewIndex, X, Z),
    swap(State, Index, NewIndex, Final).

moveRight(State, Final) :-
    location(State, X, Y, 0),
    Y < 2,
    Z is Y + 1,
    index(Index, X, Y),
    index(NewIndex, X, Z),
    swap(State, Index, NewIndex, Final).

h(State, HeuristicValue) :-
    is_goal(GoalState),
    manhattan(State, GoalState, 1, 0, HeuristicValue).

manhattan(State, GoalState, Elem, InValue, InValue) :-
    same_length(State, GoalState),
    length(State, Length),
    Elem =:= Length.

manhattan(State, GoalState, Elem, InValue, HeuristicValue) :-
    location(State, X, Y, Elem),
    location(GoalState, A, B, Elem),
    Value is InValue + abs(X - A) + abs(Y - B),
    NewElem is Elem + 1,
    manhattan(State, GoalState, NewElem, Value, HeuristicValue).
    
asked by Jose_Silva 12.12.2018 в 23:09
source

0 answers