Question about assertz

Hi Jan, Hi all,
I am using SWI version 8.3.29-29-g584873769.
My code is the following

:- table q/1 as incremental.
:- dynamic q2/1 as incremental.
:- dynamic q3/1 as incremental.

q3(1) :- assertz(q2(1)).
q(X) :- q2(X).
q(X) :- q3(X).

The following execution is ok for me :

?- q2(1).
false.

?- q3(1).
true.

?- q2(1).
true.

?- q(1).
true.

But if I stop and relaunch SWI, then I do not understand the following error when directly executing query q(1).

?- q(1).
ERROR: [Thread pdt_console_client_0_Default Process] '$idg_changed'/1: No permission to update variant `user:q(1)'
ERROR: [Thread pdt_console_client_0_Default Process] No permission to update variant `user:q(1)'
ERROR: [Thread pdt_console_client_0_Default Process] In:
ERROR: [Thread pdt_console_client_0_Default Process]   [27] assertz(q2(1))
ERROR: [Thread pdt_console_client_0_Default Process]   [24] call('$toplevel':<closure>(q/1)(1)) at c:/program files/swipl/boot/init.pl:484
ERROR: [Thread pdt_console_client_0_Default Process]   [23] reset('$toplevel':call(...),_11818,_11820) at c:/program files/swipl/boot/init.pl:572
ERROR: [Thread pdt_console_client_0_Default Process]   [22] delim(ret,'$toplevel':call(...),115413760,[]) at c:/program files/swipl/boot/tabling.pl:606
ERROR: [Thread pdt_console_client_0_Default Process]   [21] activate(ret,'$toplevel':call(...),115413760) at c:/program files/swipl/boot/tabling.pl:584
ERROR: [Thread pdt_console_client_0_Default Process]   [20] run_leader(ret,'$toplevel':call(...),fresh(118661792,115413760),_11938,_11940) at c:/program files/swipl/boot/tabling.pl:570
ERROR: [Thread pdt_console_client_0_Default Process]   [19] setup_call_catcher_cleanup('$tabling':'$idg_set_current'(_11996,<trie>(0000000006E71FF0)),'$tabling':run_leader(ret,...,...,_12014,_12016),_11984,'$tabling':finished_leader(_12026,_12028,...,...)) at c:/program files/swipl/boot/init.pl:646
ERROR: [Thread pdt_console_client_0_Default Process]   [18] create_table(<trie>(0000000006E71FF0),fresh(118661792,115413760),ret,user:q(1),'$toplevel':call(...)) at c:/program files/swipl/boot/tabling.pl:384
ERROR: [Thread pdt_console_client_0_Default Process]   [17] catch('$tabling':create_table(<trie>(0000000006E71FF0),...,ret,...,...),deadlock,'$tabling':restart_tabling(<closure>(q/1),...,...)) at c:/program files/swipl/boot/init.pl:546
ERROR: [Thread pdt_console_client_0_Default Process]   [16] start_tabling_2(<closure>(q/1),user:q(1),'$toplevel':call(...),<trie>(0000000006E71FF0),fresh(118661792,115413760),ret) at c:/program files/swipl/boot/tabling.pl:370
ERROR: [Thread pdt_console_client_0_Default Process]   [14] '$wrap$q'(1)1-st clause of '$wrap$q'/1 <no source>
ERROR: [Thread pdt_console_client_0_Default Process]   [13] toplevel_call(user:user: ...) at c:/program files/swipl/boot/toplevel.pl:1117
ERROR: [Thread pdt_console_client_0_Default Process] 
ERROR: [Thread pdt_console_client_0_Default Process] Note: some frames are missing due to last-call optimization.
ERROR: [Thread pdt_console_client_0_Default Process] Re-run your program in debug mode (:- debug.) to get more detail.

Do I miss something ?
Cheers

Christophe

My previous post comes from the fact that I wonder if there is a way to distinguish a “positive” false obtained for a fact after a proof has been found that this fact is false, from a “negative” false for a fact inferred since nothing can be proven about this fact.
For example with

p(2) :- false.

then we cannot distinguish the following answers :

?- p(2).
false.

?- p(3).
false.

Indeed, p(2) is false because we have a proof it is so, while p(3) is false because we cannot prove anything about it. Is there a way to make any distinction ?

Cheers.

Christophe

I don’t really get this. After stop and relaunch you are back at square one, no? Why would this be different this time? The error comes from trying to modify a dynamic predicate that it involved in an incremental re-evaluation. In other words, if p depends on a dynamic predicate d than (re)evaluating p may not change d.

I doubt it. That is why ASP and its recently discussed cousin sCASP introduce explicit negation, so we can state -p(2) to indicate that p(2) is explicitly known to be false. In Prolog, tabled or not, we only have NAF, negation as failure.

1 Like

OK, thank you Jan, I think I get my mistake.

Ok. So what does it mean when you implement sCASP into SWI ? Do you implement it by modifying core SWI mechanisms ? Or do you implement it by defining sCASP as an extra layer on top of NAF ?

Sorry if this is not clear, and thank you for your answers.

Christophe, sCASP is a system that was written using ciao prolog, and Jan is porting it to SWI Prolog making some enhancements along the way. You can already play with it (it is not ready for normal use): GitHub - JanWielemaker/sCASP: top-down interpreter for ASP programs with constraints

1 Like

Thanks a lot, I will have a look at the link.