I’m trying to do something odd. Basically, I’m trying to queue and delay the execution of certain clauses until later.
:- dynamic negation_queue/1 as incremental.
:- dynamic negation_commit/1 as incremental.
:- table negation_helper/1 as incremental.
negation_helper(G) :-
var(G) -> throw(user_error(negation_helper)).
% We've already committed to G
negation_helper(G) :-
negation_commit(G),
format('Already committed ~w', G),
!.
% G isn't true right now.
negation_helper(G) :-
not(G), !, fail.
% Queue G and fail.
negation_helper(G) :-
!,
negation_queue(G)
-> fail
; format('I am queueing negation ~w~n', G), assert(negation_queue(G)), format('done'), fail.
rule :-
writeln('I am reasoning, but about to block'),
negation_helper(true),
writeln('I am done').
process_queue :-
retract(negation_queue(G)),
% XXX What happens if G is no longer true?
G,
assert(negation_commit(G)).
This results in:
- rule.
I am reasoning, but about to block
I am queueing negation true
ERROR: '$idg_changed'/1: No permission to update variant `user:negation_helper(true)'
ERROR: No permission to update variant `user:negation_helper(true)'
ERROR: In:
ERROR: [23] assert(negation_queue(true))
ERROR: [22] negation_helper(true) at /home/ed/Dropbox/temp/swi/new.pl:25
ERROR: [21] call(user:<closure>(negation_helper/1)(true)) at /home/ed/Documents/swipl-devel/build/home/boot/init.pl:502
ERROR: [20] reset(user:call(...),_372,_374) at /home/ed/Documents/swipl-devel/build/home/boot/init.pl:604
ERROR: [19] delim(ret,user:call(...),94686524255520,[]) at /home/ed/Documents/swipl-devel/build/home/boot/tabling.pl:607
ERROR: [18] activate(ret,user:call(...),94686524255520) at /home/ed/Documents/swipl-devel/build/home/boot/tabling.pl:587
ERROR: [17] run_leader(ret,user:call(...),fresh(94686524300528,94686524255520),_492,_494) at /home/ed/Documents/swipl-devel/build/home/boot/tabling.pl:573
ERROR: [16] setup_call_catcher_cleanup('$tabling':'$idg_set_current'(_550,<trie>(0x561deca55c20)),'$tabling':run_leader(ret,...,...,_568,_570),_538,'$tabling':finished_leader(_580,_582,...,...)) at /home/ed/Documents/swipl-devel/build/home/boot/init.pl:679
ERROR: [15] create_table(<trie>(0x561deca55c20),fresh(94686524300528,94686524255520),ret,user:negation_helper(true),user:call(...)) at /home/ed/Documents/swipl-devel/build/home/boot/tabling.pl:388
ERROR: [14] catch('$tabling':create_table(<trie>(0x561deca55c20),...,ret,...,...),deadlock,'$tabling':restart_tabling(<closure>(negation_helper/1),...,...)) at /home/ed/Documents/swipl-devel/build/home/boot/init.pl:565
ERROR: [13] start_tabling_2(<closure>(negation_helper/1),user:negation_helper(true),user:call(...),<trie>(0x561deca55c20),fresh(94686524300528,94686524255520),ret) at /home/ed/Documents/swipl-devel/build/home/boot/tabling.pl:375
ERROR: [11] '$wrap$negation_helper'(true)1-st clause of '$wrap$negation_helper'/1 <no source>
ERROR: [10] rule at /home/ed/Dropbox/temp/swi/new.pl:30
ERROR: [9] toplevel_call(user:user:rule) at /home/ed/Documents/swipl-devel/build/home/boot/toplevel.pl:1173
ERROR:
ERROR: Note: some frames are missing due to last-call optimization.
ERROR: Re-run your program in debug mode (:- debug.) to get more detail.
I assume this error is because negation_helper/1 is invalidating its own incremental table. Is there any way to accomplish this?
negation_helper/1 does not need to be tabled, but rule does.
@jan you probably will guess by the name, but I’m experimenting with a new way of handling negation in OOAnalyzer. If this works, it might solve some of the issues we had with monotonic tabling…