una - reglas en prolog
¿Cómo puedo reemplazar una lista en Prolog? (1)
Realmente no estoy seguro de lo que estás tratando de lograr aquí, pero puedo señalar algunas cosas que me parecen síntomas de un malentendido.
En primer lugar, enlaza todas las variables en la parte superior y luego tiene esencialmente otro caso que se ve así:
NewTray = [L0,L1,L2,L3,L4,L5,L6,L7,L8,L9,L10].
Bueno, nunca asigna a NewTray
en ninguno de sus otros casos, por lo que NewTray
se va a desinstalar la mayor parte del tiempo. Eso no parece ser lo que tú quieres para mí.
En segundo lugar, sus casos tienen esta estructura:
H is 1,replace(L1,T,E,N),L1 = N;
El primer error aquí es que H is 1
; is/2
es para evaluar expresiones aritméticas; no hay diferencia entre esto y H = 1
, y la equivalencia de L1
y N
significa que este predicado completo probablemente podría escribirse como:
findLine([L0,L1,L2,L3,L4,L5,L6,L7,L8,L9,L10],1,T,E,_) :-
replace(L1,T,E,L1).
findLine([L0,L1,L2,L3,L4,L5,L6,L7,L8,L9,L10],2,T,E,_) :-
replace(L2,T,E,L2).
findLine(Line, _, _, Line).
Todavía estoy confundido por lo que estás tratando de hacer, mirando eso.
Sospecho que piensas que L1
tendrá algún valor en el camino hacia la relación y de repente tendrá un valor nuevo y diferente después de que se use la relación. Eso no es el caso enfáticamente: las variables en Prolog están ligadas exactamente una vez; su asignación L1 = N
o lo que sea, no hará que L1 "reciba un nuevo valor" (porque tal cosa no puede suceder en Prolog); en su lugar, informa a Prolog que L1 y N deben estar vinculados al mismo valor. Lo que esto significa depende de las circunstancias; si ambos son terreno y no iguales, hará que tu predicado falle, por ejemplo, pero si alguno de ellos no es terreno, aceptará el valor del otro.
Estoy viendo lo que estás haciendo aquí y no puedo evitar pensar que esencialmente estás tratando de hacer esto:
replace([], _, _, []).
replace([H|T], 1, X, [X|T]).
replace([H|T], N, X, [H|Replaced]) :-
N > 1, succ(N0, N), replace(T, N0, X, Replaced).
Úselo así:
?- replace([1,2,3,4,5], 3, foo, Result).
Result = [1, 2, foo, 4, 5]
Simplemente no puedo entender lo que intentas hacer, y no sé por qué te molestas en vincular todas las variables de tu lista de una vez si no las necesitas todas en una vez.
De todos modos, espero que esto ayude! Tal vez si nos muestras más de lo que estás tratando de hacer será más claro cómo podemos ayudar.
Editar : Elaboración en =
y unificación
Juguemos con =
y veamos qué pasa:
?- X = 3.
X = 3.
Probablemente nada sorprendente sobre esto.
?- 3 = X.
X = 3.
La unificación es diferente de la asignación. Como puede ver, no es direccional. Esta línea no habría funcionado en ningún otro idioma.
?- X = [1,Y,3].
X = [1, Y, 3].
Tenga en cuenta que Prolog no tiene problemas para que las variables permanezcan libres.
?- X = [1,Y,3], Y = 2.
X = [1, 2, 3],
Y = 2.
Ahora, debido a que Y es el mismo en ambas posiciones, cuando vinculaste Y a 2, el valor medio en X se convirtió en 2 también. Existen estructuras de datos exclusivas de Prolog que hacen uso de esta característica (listas de diferencias).
?- X = [1,Y,3], Q = X, Q = [1,2,3].
X = Q, Q = [1, 2, 3],
Y = 2.
Ahora lo que hace que esto sea interesante es que no le dijimos explícitamente a Prolog que Y es 2. Prolog lo dedujo por unificación. Puedes ver algunos ejemplos más de eso aquí:
?- X = [H|T], H = 3, T = [4,5].
X = [3, 4, 5],
H = 3,
T = [4, 5].
Entonces aquí dijimos, X está compuesto de H y T y luego le dijimos lo que H y T son. Pero la unificación de Prolog no se preocupa demasiado por el orden en que haces las cosas:
?- X = [H|T], X = [1,2,3].
X = [1, 2, 3],
H = 1,
T = [2, 3].
La unificación es transitiva.
Entonces, ¿qué sucede cuando Prolog no puede unificarse?
?- X = [1,Y,3], Q = X, Q = [1,2,3], Y = 4.
false.
Y tiene que ser 2 para el primer paso, pero tiene que ser 4 para el último paso. Una vez que una variable está vinculada, no hay cambio. Esta es solo una forma más compleja de decir:
?- X = 2, X = 4.
false.
Prolog no tiene "asignables", solo variables.
Creo que es muy fácil, pero no tengo idea de cómo hacerlo. Lo intenté por atribución, al hacer una lista recibí otra lista pero no funcionó.
% H is the head of a coordenate and T the tail
% E is the element that will be placed in the position T
findLine([L0,L1,L2,L3,L4,L5,L6,L7,L8,L9,L10],H,T,E,NewTray) :-
H is 1,replace(L1,T,E,N),L1 = N;
H is 2,replace(L2,T,E,N),L2 = N;
...
H is 10,replace(L10,T,E,N),L10 = N;
NewTray = [L0,L1,L2,L3,L4,L5,L6,L7,L8,L9,L10].
Necesito que L1 sea el N en esta cláusula, no sé cómo puedo crear una cláusula para modificar el L1 dentro de la cláusula findLine. Pensé en crear una cláusula para eliminar todos los elementos y agregar los nuevos uno por uno y llamar esto al lugar de atribución:
%L is the list, C a counter and N the new list
rewrite(L,C,N) :-
Q is C,
removeByIndex(Q,L,R),
(Q /== 0 -> rewrite(R,Q-1,N), !.
removeByIndex(0,[_|T],T):- !.
removeByIndex(I,[H|T],R):- X is I - 1, removeByIndex(X, T, Y), insert(H, Y, R).
Pero continúo con el mismo problema: la L1 no se modifican :(
La idea es modificar una línea y reemplazarla en la bandeja.
PD: lo siento por mi inglés, pero los temas prolog son casi inantes en el foro portugués