Утверждение и откат для эмуляции глобальных переменных
Я делаю это для эмуляции глобальных переменных:
update_queue(NewItem) :-
global_queue(Q),
retractall(global_queue(Q)),
append(Q, [NewItem], NewQ),
assert(global_queue(NewQ)).
Есть ли другой способ? (Кроме передачи переменных в качестве аргументов). Не обязательно более эффективный, мне просто любопытно.
1 ответ
В SWI-Prolog есть также nb_setval/2 и b_setval/2 (и соответствующий "_getval/2"). Используйте time/1, чтобы увидеть, является ли это более эффективным. Также комментарий к представлению очереди: Если вы представляете начальную очередь в виде пары переменных QQ, вы можете добавить элемент в постоянное время с помощью:
insert_q0_q(E, Q-[E|Rest], Q-Rest).
то есть вы добавляете элемент E в очередь путем дальнейшей инстанцирования хвоста (то есть второго элемента пары), и новый хвост снова становится свободной переменной. Я оставляю удаление элемента спереди (также в постоянном времени) в качестве упражнения; подсказка: когда первый элемент пары является переменной, очередь в этом представлении пуста. Как правило, глобальные переменные значительно усложняют отладку, поскольку вы не можете тестировать предикаты изолированно. В качестве альтернативы передаче очереди в качестве аргументов (о которой вы уже упоминали), рассмотрите возможность использования нотации DCG для ее неявного прохождения. Это часто делает код более читабельным, особенно если для доступа к "глобальным" аргументам нужен только небольшой набор предикатов.