2012-05-18 20 views
5

tengo una lista que se crea de la siguiente manera:Cómo crear variable global en el prólogo

tab([(top,left),(top,middle),(top,right),(center,left),(center,middle), 
    (center,right),(bottom,left),(bottom,middle),(bottom,right)]). 

deseo de crear un AllPosition variable global que es una ficha. Así que hice lo siguiente:

tab(AllPos). 

es esto correcto?

Luego tengo que seguir el problema: Tengo una función que recibe uno de los pares en la pestaña. Que deseo eliminar Así que hice esto:

place(Line, Column, Tab) :- 
AllPos \== [_,_] /*while AllPos isn't empty - not sur if this is done this way*/ -> (member((Line,Column), AllPos) -> (erase(AllPos, (Line,Column), AllPos)). 

donde erase(List, Element, NewList) borra el elemento de elemento de la lista y crea una nueva lista newList igual a la lista pero sin elemento. Ambas funciones member y erase están funcionando.

La cosa es ... Como habrás notado, uso AllPos en todas partes. Eso es porque quiero, quiero modificarlo para poder usarlo más tarde (después de haber eliminado algunos elementos) en otra función. Es mi lógica ¿verdad? ¿Podré usar AllPos modificado en otra función? Gracias

+0

Por favor, vea también las preguntas y respuestas sobre cómo [** evitar las variables globales **] (http://stackoverflow.com/questions/19005042/how-to-avoid-using-assert-and-retractall-in -prolog-to-implement-global-or-state) en Prolog. – mat

Respuesta

0

En resumen: no, su lógica no es la correcta. Hay varios problemas menores y errores con su código, pero el problema más grande es la premisa básica. Parece que estás pensando en el problema de la manera equivocada. En general, si intentas actualizar el estado global en un programa Prolog, necesitas replantear tu diseño. Estado está más generalmente llevado por los argumentos de los predicados, por lo que en lugar de unificar AllTabs en el cuerpo de place/4, lo que habría esperado el conjunto de la corriente Tabs que se pasa como argumento. Si realmente desea actualizar el estado global de su programa, entonces debe consultar los predicados assert y .

Algunos puntos específicos:

tab(AllPos). 

Esto declara un predicado con una variable no unida en la cabeza. Es más o menos sin sentido (que se podía leer está en "que es el caso que tab es verdad de algo, pero no tenemos información acerca de lo que es el caso de").

AllPos \== [_,_] 

Este uso de AllPos está en un alcance diferente a tab/1, por lo que además de compartir la misma secuencia de caracteres en el nombre de la variable, las dos usos de AllPos no tienen ninguna relación en absoluto.

1

añadir a la respuesta de Ian:

generalmente usando aserción/retracción es lento.muchas implementaciones Prolog tienen formas más eficientes para las variables globales mutables (por ejemplo de cheque SWI-Prolog lib)

ahora, si quieres una inmutable variable global que se puede codificar casi igual que lo hizo; va a "declarar" como myvar(42). sino para utilizarlo tendrá que hacer esto:

foo:- 
    myvar(Var), 
    do_something(Var). 

vez más, el uso de variables globales mutables no está muy recomendado y puede dar lugar a muy, muy malo y difícil de detectar errores debido al retroceso.

+0

[El eslabón de esta respuesta] (http://www.swi-prolog.org/pldoc/doc_for?object=section%282,%276.3%27,swi%28%27/doc/Manual/gvar.html% 27% 29% 29) parece estar roto. –

+0

@AndersonGreen, ¡arreglos! –

4

En SWI-Prolog puede usar: b_setval(name, value) y b_getval(name, value). Y en caso de que no desee que los valores vuelvan a cambiar en caso de retroceso, puede hacerlos globales reales usando: nb_setval(name, value) y nb_getval(name, value).

Así, por ejemplo, si tiene un programa y desea comprobar la frecuencia con que pasó por un camino determinado, puede utilizar:

recursive(100). 
recursive(X) :- add, Y is X + 1, recursive(Y). 

add :- nb_getval(counter, C), CNew is C + 1, nb_setval(counter, CNew). 

testRecursion 
:- 
    % Set counter to zero 
    nb_setval(counter, 0), 

    % Run some code with 'add' 
    recursive(0), !, 

    % Print the results 
    nb_getval(counter, CounterValue), 
    write('Steps: '), writeln(CounterValue). 

Esto es bueno para algunos casos experimentales, pero en general, usted quiere evitar variables globales en Prolog porque Prolog significa programación en lógica.