Prolog - encallado en esta regla, me devuelve false siempre que ejecuto la llamada recursiva

   
Vista:

encallado en esta regla, me devuelve false siempre que ejecuto la llamada recursiva

Publicado por alex (7 intervenciones) el 19/04/2017 00:11:16
Muy buenas, estoy haciendo una práctica en prolog para la asignatura de teoría de los lenguajes y estoy encallado en esta regla, me devuelve false siempre que la ejecuto, y es la llamada recursiva, llevo varios días sin saber que hacer, ayuda please.

1
2
3
4
5
6
7
8
9
10
11
12
jump(node(N,L,Board,s(F,R),Fr),nnode(N,L1,BoardNuevo,s(F1,R1),[s(F1,R1)|Fr])):-F1 is F+2,R1 is R+1, validSquare(N,s(F1,R1),Board,BoardNuevo),L1 is L + 1.
jump(node(N,L,Board,s(F,R),Fr),nnode(N,L1,BoardNuevo,s(F1,R1),[s(F1,R1)|Fr])):-F1 is F+1,R1 is R+2, validSquare(N,s(F1,R1),Board,BoardNuevo),L1 is L + 1.
jump(node(N,L,Board,s(F,R),Fr),nnode(N,L1,BoardNuevo,s(F1,R1),[s(F1,R1)|Fr])):-F1 is F-1,R1 is R+2, validSquare(N,s(F1,R1),Board,BoardNuevo),L1 is L + 1.
jump(node(N,L,Board,s(F,R),Fr),nnode(N,L1,BoardNuevo,s(F1,R1),[s(F1,R1)|Fr])):-F1 is F-2,R1 is R+1, validSquare(N,s(F1,R1),Board,BoardNuevo),L1 is L + 1.
jump(node(N,L,Board,s(F,R),Fr),nnode(N,L1,BoardNuevo,s(F1,R1),[s(F1,R1)|Fr])):-F1 is F-2,R1 is R-1, validSquare(N,s(F1,R1),Board,BoardNuevo),L1 is L + 1.
jump(node(N,L,Board,s(F,R),Fr),nnode(N,L1,BoardNuevo,s(F1,R1),[s(F1,R1)|Fr])):-F1 is F-1,R1 is R-2, validSquare(N,s(F1,R1),Board,BoardNuevo),L1 is L + 1.
jump(node(N,L,Board,s(F,R),Fr),nnode(N,L1,BoardNuevo,s(F1,R1),[s(F1,R1)|Fr])):-F1 is F+1,R1 is R-2, validSquare(N,s(F1,R1),Board,BoardNuevo),L1 is L + 1.
jump(node(N,L,Board,s(F,R),Fr),nnode(N,L1,BoardNuevo,s(F1,R1),[s(F1,R1)|Fr])):-F1 is F+2,R1 is R-1, validSquare(N,s(F1,R1),Board,BoardNuevo),L1 is L + 1.
 
 
recorrerBT1(node(N,L,Board,s(F,R),Fr),Nodo):-N1 is N*N, L==N1,Nodo=node(N,L,Board,s(F,R),Fr),!.
recorrerBT1(node(N,L,Board,s(F,R),Fr),Nodo):- jump(node(N,L,Board,s(F,R),Fr),nodo1(N,L1,Board1,s(F1,R1),Fr1)),recorrerBT1(nodo1(N,L1,Board1,s(F1,R1),Fr1),Nodo).


validSquare se ocupa de devolver si F1 y r1 son válidos, y jump me da una serie de moviemientosque son los que haría un caballo en un tablero, mi problema viene con recorrerBT1, al hacer la llamada recursiva me manda un false, y no se el motivo, lo que quiero es que me de el node() que contendrá el camino completo de movimientos, pero siempre me dá false, bueno a ver si alguien puede ayudarme, por que toy desesperadito.
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder

encallado en esta regla, me devuelve false siempre que ejecuto la llamada recursiva

Publicado por manuel (2 intervenciones) el 19/04/2017 16:58:24
podrias mandarme el ejercicio original?
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

encallado en esta regla, me devuelve false siempre que ejecuto la llamada recursiva

Publicado por ALEX (7 intervenciones) el 19/04/2017 20:39:06
El problema es el viaje del caballo, desde una posición dada tiene que darte todo el camino dando un tamaño de tablero que recorra cada posición contando que los únicos movimientos que puedo hacer son los del caballo, estos serían ((2,1),(1,2).(-1,2)(-2,1).(-2,-1).(-1,-2).(1,-2).(2,-1).
Todo esto se guarda en un predicado, este predicado tiene node(tamañotablero, longitudcaminoactual,tablero,posicionactual,caminorecorrido).
Me vale con dar un camino y si no devolver false.
Jump me da los posibles caminos que puedes coger desde una valor de node, que sería desde un punto con su camino. Jump decide los posilbles movimientos en vase a la regla validSquare que dandole el tablero y la posición te dice si esta posición es válida, es de decir si no ha pasado antes `por esa posición y si no sale del tablero. Jump devuelve un predicado con todos los datos actualizados por cada movimiento posible.
Mi problema viene cuando utilizo recorrerBT1, necesito que esta regla me busque por medio de backtraking cada posible camino y que me haga vuelta atrás mirando por cada nuevo camino posible que me da jump si hay solución. Pero tal como la tengo me da false, he intentando utilizar esta regla metiendo un tamaño de tablero de 5, y una longitud de camino hecho de 24, con lo que al hacer la llamada recursiva con el cualquier nodo dado por jump éste nodo tendría un camino recorrido de 25 y debería devolverme ese node(_,_,_,_,_)(ya que acabaría con un corte al entrar en la primera regla), pero en vez de esto me da un false.

No se que hacer llevo 5 días con esto.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

encallado en esta regla, me devuelve false siempre que ejecuto la llamada recursiva

Publicado por alex (7 intervenciones) el 19/04/2017 20:41:43
Perdona, no hay problema en mandarte el ejercicio original, lo único que tampoco quiero liarte mucho con esto ya que con lo anterior no he tenido problema, esto es casi lo último y no entiendo que hago mal. Te doy las gracias por el interés y si quieres el ejercicio original yo te lo mando sin problema. Gracias otra vez.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

haciendo esta regla también me da false.

Publicado por alex (7 intervenciones) el 19/04/2017 20:54:36
Haciendo esta regla me da false,no se que hago mal por que metiendo los mismos parámetros para jump me da los nodos, y meto exactamente lo mismo.

recorrerBT1(node(N,L,Board,s(F,R),Fr),nodo1(N,L1,Board1,s(F1,R1),Fr1)):- jump(node(N,L,Board,s(F,R),Fr),nodo1(N,L1,Board1,s(F1,R1),Fr1)).

para jump metieno esto

jump(node(3,1,[[true,true,true],[true,true,true],[true,true,true]],s(1,1),[s(1,1)]),Nodo1).
Nodo1 = nnode(3, 2, [[true, true, true], [true, true, true], [true, false, true]], s(3, 2), [s(3, 2), s(1, 1)]) .

me da el nodo pero haciendolo para esto

recorrerBT1(node(3,1,[[true,true,true],[true,true,true],[true,true,true]],s(1,1),[s(1,1)]),Nodo1).
false.
nu se....
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

haciendo esta regla también me da false.

Publicado por Manuel Alejandro (5 intervenciones) el 20/04/2017 00:06:18
esto a mi me funciona y creo que es lo que quieres

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
len([],0).
len([_|L],N):- len(L,N2), N is 1 + N2.
 
contain([X|_],X).
contain([Y|L],X):- Y\=X, contain(L,X).
 
can_move(R,C,I,J,Path):- I =< R, I >= 1, J =< C, J >= 1, not(contain(Path, par(I,J))).
 
knight_travel(R,C,_,_,CurPath,CurPath):- SZ is R * C, len(CurPath,LEN), SZ is LEN.
knight_travel(R,C,I,J,CurPath,Path):- SZ is R * C, len(CurPath,LEN), SZ \= LEN,
	      (
	       ( I2 is I+2, J2 is J+1, can_move(R,C,I2,J2,CurPath), knight_travel(R,C,I2,J2,[par(I2,J2)|CurPath],Path) ) ;
	       ( I2 is I+1, J2 is J+2, can_move(R,C,I2,J2,CurPath), knight_travel(R,C,I2,J2,[par(I2,J2)|CurPath],Path) ) ;
	       ( I2 is I-1, J2 is J+2, can_move(R,C,I2,J2,CurPath), knight_travel(R,C,I2,J2,[par(I2,J2)|CurPath],Path) ) ;
	       ( I2 is I-2, J2 is J+1, can_move(R,C,I2,J2,CurPath), knight_travel(R,C,I2,J2,[par(I2,J2)|CurPath],Path) ) ;
	       ( I2 is I-2, J2 is J-1, can_move(R,C,I2,J2,CurPath), knight_travel(R,C,I2,J2,[par(I2,J2)|CurPath],Path) ) ;
	       ( I2 is I-1, J2 is J-2, can_move(R,C,I2,J2,CurPath), knight_travel(R,C,I2,J2,[par(I2,J2)|CurPath],Path) ) ;
	       ( I2 is I+1, J2 is J-2, can_move(R,C,I2,J2,CurPath), knight_travel(R,C,I2,J2,[par(I2,J2)|CurPath],Path) ) ;
	       ( I2 is I+2, J2 is J-1, can_move(R,C,I2,J2,CurPath), knight_travel(R,C,I2,J2,[par(I2,J2)|CurPath],Path) )
	      ).

R es la cantidad de rows, C la cantidad columns, I, J son las coordenadas de la posicion actual,
CurPath es el camino recorrido hasta ahora, Path es el camino final invertido.
?- knight_travel(R,C,1,1,[par(1,1)],Path).
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
1
Comentar

haciendo esta regla también me da false.

Publicado por alex (7 intervenciones) el 21/04/2017 00:32:47
Muchas gracias, entiendo lo k hace, mi problema es k debo utilizar unas reglas predefinidas como jump, voy a mirarme bien este ejercicio e intentar adaptarlo. De nuevo muchisimas gracias por tu ayuda.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

haciendo esta regla también me da false.

Publicado por Manuel Alejandro (5 intervenciones) el 21/04/2017 03:02:30
Quizas asi te ayude mejor, es la misma idea que en tu codigo

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
len([],0).
len([_|L],N):- len(L,N2), N is 1 + N2.
 
contain([X|_],X).
contain([Y|L],X):- Y\=X, contain(L,X).
 
can_move(R,C,I,J,Path):- I =< R, I >= 1, J =< C, J >= 1, not(contain(Path, par(I,J))).
 
jump(R,C,I,J,CurPath,I2,J2):- I2 is I+2, J2 is J+1, can_move(R,C,I2,J2,CurPath).
jump(R,C,I,J,CurPath,I2,J2):- I2 is I+1, J2 is J+2, can_move(R,C,I2,J2,CurPath).
jump(R,C,I,J,CurPath,I2,J2):- I2 is I-1, J2 is J+2, can_move(R,C,I2,J2,CurPath).
jump(R,C,I,J,CurPath,I2,J2):- I2 is I-2, J2 is J+1, can_move(R,C,I2,J2,CurPath).
jump(R,C,I,J,CurPath,I2,J2):- I2 is I-2, J2 is J-1, can_move(R,C,I2,J2,CurPath).
jump(R,C,I,J,CurPath,I2,J2):- I2 is I-1, J2 is J-2, can_move(R,C,I2,J2,CurPath).
jump(R,C,I,J,CurPath,I2,J2):- I2 is I+1, J2 is J-2, can_move(R,C,I2,J2,CurPath).
jump(R,C,I,J,CurPath,I2,J2):- I2 is I+2, J2 is J-1, can_move(R,C,I2,J2,CurPath).
 
knight_travel(R,C,_,_,CurPath,CurPath):- SZ is R * C, len(CurPath,LEN), SZ is LEN,!.
knight_travel(R,C,I,J,CurPath,Path):- jump(R,C,I,J,CurPath,I2,J2), knight_travel(R,C,I2,J2,[par(I2,J2)|CurPath],Path).
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
2
Comentar

haciendo esta regla también me da false.

Publicado por ALEX (7 intervenciones) el 21/04/2017 08:16:28
Muchas gracias Manuel, te cuento como me queda.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

haciendo esta regla también me da false.

Publicado por alex (7 intervenciones) el 22/04/2017 00:38:35
wenas,
he intentado adaptar lo que me has mandado pero me ha sido imposible, ya que necesito crear la función jump, que se encarga de darme los nodos de cada posible movimiento a partir de otro nodo. El problema es que tengo que duplicar las reglas jump de esta manera:

jump(node(N,L,Board,s(F,R),Fr),nnode(N,L1,BoardNuevo,s(F1,R1),[s(F1,R1)|Fr])):-F1 is F+2,R1 is R+1, validSquare(N,s(F1,R1),Board,BoardNuevo),L1 is L + 1.

jump(node(N,L,Board,s(F,R),Fr),nnode(N,L1,BoardNuevo,s(F1,R1),[s(F1,R1)|Fr])):-F1 is F+1,R1 is R+2, validSquare(N,s(F1,R1),Board,BoardNuevo),L1 is L + 1.

jump(node(N,L,Board,s(F,R),Fr),nnode(N,L1,BoardNuevo,s(F1,R1),[s(F1,R1)|Fr])):-F1 is F-1,R1 is R+2, validSquare(N,s(F1,R1),Board,BoardNuevo),L1 is L + 1.

jump(node(N,L,Board,s(F,R),Fr),nnode(N,L1,BoardNuevo,s(F1,R1),[s(F1,R1)|Fr])):-F1 is F-2,R1 is R+1, validSquare(N,s(F1,R1),Board,BoardNuevo),L1 is L + 1.

jump(node(N,L,Board,s(F,R),Fr),nnode(N,L1,BoardNuevo,s(F1,R1),[s(F1,R1)|Fr])):-F1 is F-2,R1 is R-1, validSquare(N,s(F1,R1),Board,BoardNuevo),L1 is L + 1.

jump(node(N,L,Board,s(F,R),Fr),nnode(N,L1,BoardNuevo,s(F1,R1),[s(F1,R1)|Fr])):-F1 is F-1,R1 is R-2, validSquare(N,s(F1,R1),Board,BoardNuevo),L1 is L + 1.

jump(node(N,L,Board,s(F,R),Fr),nnode(N,L1,BoardNuevo,s(F1,R1),[s(F1,R1)|Fr])):-F1 is F+1,R1 is R-2, validSquare(N,s(F1,R1),Board,BoardNuevo),L1 is L + 1.

jump(node(N,L,Board,s(F,R),Fr),nnode(N,L1,BoardNuevo,s(F1,R1),[s(F1,R1)|Fr])):-F1 is F+2,R1 is R-1, validSquare(N,s(F1,R1),Board,BoardNuevo),L1 is L + 1.

================== duplicado de llamadas, cambio el orden, nnode entra primero en el predicado y después node =========

jump(nnode(N,L,Board,s(F,R),Fr),node(N,L1,BoardNuevo,s(F1,R1),[s(F1,R1)|Fr])):-F1 is F+2,R1 is R+1, validSquare(N,s(F1,R1),Board,BoardNuevo),L1 is L + 1.

jump(nnode(N,L,Board,s(F,R),Fr),node(N,L1,BoardNuevo,s(F1,R1),[s(F1,R1)|Fr])):-F1 is F+1,R1 is R+2, validSquare(N,s(F1,R1),Board,BoardNuevo),L1 is L + 1.

jump(nnode(N,L,Board,s(F,R),Fr),node(N,L1,BoardNuevo,s(F1,R1),[s(F1,R1)|Fr])):-F1 is F-1,R1 is R+2, validSquare(N,s(F1,R1),Board,BoardNuevo),L1 is L + 1.

jump(nnode(N,L,Board,s(F,R),Fr),node(N,L1,BoardNuevo,s(F1,R1),[s(F1,R1)|Fr])):-F1 is F-2,R1 is R+1, validSquare(N,s(F1,R1),Board,BoardNuevo),L1 is L + 1.

jump(nnode(N,L,Board,s(F,R),Fr),node(N,L1,BoardNuevo,s(F1,R1),[s(F1,R1)|Fr])):-F1 is F-2,R1 is R-1, validSquare(N,s(F1,R1),Board,BoardNuevo),L1 is L + 1.

jump(nnode(N,L,Board,s(F,R),Fr),node(N,L1,BoardNuevo,s(F1,R1),[s(F1,R1)|Fr])):-F1 is F-1,R1 is R-2, validSquare(N,s(F1,R1),Board,BoardNuevo),L1 is L + 1.

jump(nnode(N,L,Board,s(F,R),Fr),node(N,L1,BoardNuevo,s(F1,R1),[s(F1,R1)|Fr])):-F1 is F+1,R1 is R-2, validSquare(N,s(F1,R1),Board,BoardNuevo),L1 is L + 1.

jump(nnode(N,L,Board,s(F,R),Fr),node(N,L1,BoardNuevo,s(F1,R1),[s(F1,R1)|Fr])):-F1 is F+2,R1 is R-1, validSquare(N,s(F1,R1),Board,BoardNuevo),L1 is L + 1.


recorrerBT1(node(N,L,Board,s(F,R),Fr),Nodo):-N1 is N*N, L==N1,Nodo=node(N,L,Board,s(F,R),Fr),!.

recorrerBT(Node):-solucion(Node).
recorrerBT(Node):-sucesor(Node,NNuevo), recorrerBT(NNuevo).

solucion(node(N,L,Board,s(F,R),Fr)):-fullPath(node(N,L,Board,s(F,R),Fr)),write(Fr).

sucesor(Node,NNuevo):-jump(Node,NNuevo).

Bien con esto he conseguido que me de la solución para el tablero de tamaño 5, pero para el 6 la búsqueda se queda colgada, si no duplico las llamadas a jump me sale false.
No entiendo este comportamiento y no se como cambiar el jump, al parecer el problema viene por que una vez jump me da todos los resultados posibles me acaba devolviendo un false, no se como hacer que ese último valor false no me aparezca saliendo sólo los nodos con los posibles movimentos, he intentado hacer cortes pero no soluciono nada y acaba por faltarme resultados. Si alguien puede explicarme que problema hay se lo agradecería muchísimo.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar