Утверждение и откат для эмуляции глобальных переменных - PullRequest
1 голос
/ 22 апреля 2011

Я делаю это для эмуляции глобальных переменных:

update_queue(NewItem) :-
    global_queue(Q),
    retractall(global_queue(Q)),
    append(Q, [NewItem], NewQ),
    assert(global_queue(NewQ)).

Есть ли другой способ?(Кроме передачи переменных в качестве аргументов).Не обязательно более эффективный, мне просто любопытно.

1 Ответ

5 голосов
/ 22 апреля 2011

В SWI-Prolog есть также nb_setval / 2 и b_setval / 2 (и соответствующий «_getval / 2»).Используйте time / 1, чтобы увидеть, является ли это более эффективным.Также комментарий к представлению очереди: Если вы представляете начальную очередь в виде пары переменных QQ, вы можете добавлять элемент в постоянное время с помощью:

insert_q0_q(E, Q-[E|Rest], Q-Rest).

, то есть вы добавляете элемент E кочереди путем дальнейшего создания экземпляра хвоста (т. е. второго элемента пары), и новый хвост снова становится свободной переменной.Я оставляю удаление элемента спереди (также в постоянном времени) в качестве упражнения;подсказка: когда первый элемент пары является переменной, очередь в этом представлении пуста.Как правило, глобальные переменные значительно усложняют отладку, поскольку вы не можете тестировать предикаты изолированно.В качестве альтернативы передаче очереди в качестве аргументов (о которой вы уже упоминали), рассмотрите возможность использования нотации DCG для ее неявного прохождения.Это часто делает код более читабельным, особенно если для доступа к «глобальным» аргументам нужен только небольшой набор предикатов.

...