# Possible database update problem

**URL:** <https://swi-prolog.discourse.group/t/possible-database-update-problem/9862>\
**Category:** General\
**Created:** [October 13, 2026, 10:25am UTC](https://swi-prolog.discourse.group/t/possible-database-update-problem/9862 "2026-10-13T10:25:14Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![stassa.p](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/stassa.p/32/712_2.png) [@stassa.p](https://swi-prolog.discourse.group/u/stassa.p)\
**Post date:** [October 13, 2026, 10:25am UTC](https://swi-prolog.discourse.group/t/possible-database-update-problem/9862/1 "2026-10-13T10:25:14Z")

</div>

I’m on the latest daily build for windows (version 10.1.18-3-gf379af528). I noticed that some times the database state is not correctly updated after I make a change to my code and call make/0.

For example, I remove a couple of clauses from my program after which the program should fail, then I call make/0 and when I call my program at the top level it succeeds.

So I start a fresh session without making any changes to my code and the same query succeeds. The difference between the two sessions is that one was updated with make/0 and the other by re-consulting the source file in a fresh session.

More confusingly, when I list my program with listing/0 in the session where my program succeeds, I see the removed clauses are not there. And yet my program behaves as if they are (and I can see that when I trace it).

This doesn’t seem to happen all the time, but I’ll try to make a simple example as much as I can.

Btw, I’m working with some DCGs so the problem may be with the DCG interpreter. Or not.

---

<div class="post-metadata">

**Author:** ![stassa.p](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/stassa.p/32/712_2.png) [@stassa.p](https://swi-prolog.discourse.group/u/stassa.p)\
**Post date:** [October 13, 2026, 10:44am UTC](https://swi-prolog.discourse.group/t/possible-database-update-problem/9862/2 "2026-10-13T10:44:46Z")

</div>

OK, this is not a _simple_ example but I’m not sure how to make this simpler.

This is the output of two sessions, the first one where my query succeeds when it should fail and the second when it fails correctly. I also list the contents of the database which are the same in both sessions (and this is why I suspect a bug in SWI rather than a bug in my code).

First session, succeeds when it should fail:

```prolog
119 ?- _I = 9, ground_csg(abc,[a,b,c],['S'],_I,Ps).
Ps = [a, a, a, b, b, b, c, c, c] .

120 ?- listing(abc).
grammars:abc(['S'|Ss], [a, 'S', 'B', 'C'|A], B) :-
    abc(Ss, A, B).
grammars:abc(['S'|Ss], [a, 'B', 'C'|A], B) :-
    abc(Ss, A, B).
grammars:abc(['C', 'B'|Ss], ['B', 'C'|A], B) :-
    !,
    C=A,
    abc(Ss, C, B).
grammars:abc([a, 'B'|Ss], [a, b|A], B) :-
    !,
    C=A,
    abc(Ss, C, B).
grammars:abc([b, 'B'|Ss], [b, b|A], B) :-
    !,
    C=A,
    abc(Ss, C, B).
grammars:abc([b, 'C'|Ss], [b, c|A], B) :-
    !,
    C=A,
    abc(Ss, C, B).
grammars:abc([c, 'C'|Ss], [c, c|A], B) :-
    !,
    C=A,
    abc(Ss, C, B).
grammars:abc(['B'|Ss], ['B'|A], B) :-
    !,
    C=A,
    abc(Ss, C, B).
grammars:abc(['C'|Ss], ['C'|A], B) :-
    !,
    C=A,
    abc(Ss, C, B).
grammars:abc([b|Ss], [b|A], B) :-
    !,
    C=A,
    abc(Ss, C, B).
grammars:abc([c|Ss], [c|A], B) :-
    !,
    C=A,
    abc(Ss, C, B).
grammars:abc([], A, B) :-
    A=B.

true.

```

Second session, fails when it should fail:

```prolog
101 ?- _I = 9, ground_csg(abc,[a,b,c],['S'],_I,Ps).
false.

102 ?- listing(abc).
grammars:abc(['S'|Ss], [a, 'S', 'B', 'C'|A], B) :-
    abc(Ss, A, B).
grammars:abc(['S'|Ss], [a, 'B', 'C'|A], B) :-
    abc(Ss, A, B).
grammars:abc(['C', 'B'|Ss], ['B', 'C'|A], B) :-
    !,
    C=A,
    abc(Ss, C, B).
grammars:abc([a, 'B'|Ss], [a, b|A], B) :-
    !,
    C=A,
    abc(Ss, C, B).
grammars:abc([b, 'B'|Ss], [b, b|A], B) :-
    !,
    C=A,
    abc(Ss, C, B).
grammars:abc([b, 'C'|Ss], [b, c|A], B) :-
    !,
    C=A,
    abc(Ss, C, B).
grammars:abc([c, 'C'|Ss], [c, c|A], B) :-
    !,
    C=A,
    abc(Ss, C, B).
grammars:abc(['B'|Ss], ['B'|A], B) :-
    !,
    C=A,
    abc(Ss, C, B).
grammars:abc(['C'|Ss], ['C'|A], B) :-
    !,
    C=A,
    abc(Ss, C, B).
grammars:abc([b|Ss], [b|A], B) :-
    !,
    C=A,
    abc(Ss, C, B).
grammars:abc([c|Ss], [c|A], B) :-
    !,
    C=A,
    abc(Ss, C, B).
grammars:abc([], A, B) :-
    A=B.

true.

```

Note that the listing is the same in both sessions. Unless I’m missing something (possible) the behaviour should be the same in both sessions, if both sessions are working off the same database.

This is the code. First my DCG, with the rule for ‘a’ commented-out so that it should fail:

```prolog
abc(['S'|Ss]) --> [a,'S','B','C'], abc(Ss).
abc(['S'|Ss]) --> [a,'B','C'], abc(Ss).
abc(['C','B'|Ss]) --> ['B','C'], !, abc(Ss).
abc([a,'B'|Ss]) --> [a,b], !, abc(Ss).
abc([b,'B'|Ss]) --> [b,b], !, abc(Ss).
abc([b,'C'|Ss]) --> [b,c], !, abc(Ss).
abc([c,'C'|Ss]) --> [c,c], !, abc(Ss).

abc(['B'|Ss]) --> ['B'], !, abc(Ss).
abc(['C'|Ss]) --> ['C'], !, abc(Ss).
%abc([a|Ss]) --> [a], !, abc(Ss).
abc([b|Ss]) --> [b], !, abc(Ss).
abc([c|Ss]) --> [c], !, abc(Ss).
abc([]) --> [].

```

And here’s the meta-interpreter in case it’s needed to test this:

```prolog
%! ground_csg(+Symbol,+Terminals,+Input,+Length,?String)
%! is nondet.
%
% Meta-interpreter for Context Sensitive Grammars in DCG notation.
%       
ground_csg(S,Ts,Is,K,Os):-
        N = K
        ,parse(S,Is,Ss)
        ,ground_csg_(S,Ts,Ss,N,Os).

%! ground_csg_(+Symbol,+Terminals,+Input,+K,-Output) is nondet.
%
% Business end of ground_csg/5.
%
ground_csg_(_S,Ts,Is,N,Is):-
        length(Is,M)
        ,M =:= N
        ,terminal_string(Ts,Is)
        ,!.
ground_csg_(S,Ts,Is,N,Os):-
        length(Is,M)
        ,M =< N
        ,\+ terminal_string(Ts,Is)
        ,parse(S,Is,Ss)
        ,ground_csg_(S,Ts,Ss,N,Os).

%! parse(+Symbol,+Inputs,-Parse) is nondet.
%
% Thin wrapper around phrase/3 to setup a parse.
%
parse_(S,Is,Ss):-
        S_ =.. [S,Ss]
        ,phrase(S_,Is).
parse(S,Is,Ss):-
        S_ =.. [S,Is]
        ,phrase(S_,Ss).

%! terminal_string(+Terminals,+String) is det.
%
% True if String is made up of only Terminals.
%
terminal_string(Ts,Ss):-
        maplist(sort,[Ts,Ss],[Ts_s,Ss_s])
        ,ord_subset(Ss_s,Ts_s).

```

---

<div class="post-metadata">

**Author:** ![jan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jan/32/4_2.png) [@jan](https://swi-prolog.discourse.group/u/jan)\
**Post date:** [October 13, 2026, 11:56am UTC](https://swi-prolog.discourse.group/t/possible-database-update-problem/9862/3 "2026-10-13T11:56:25Z")

</div>

> [@stassa.p](#):
>
> OK, this is not a _simple_ example but I’m not sure how to make this simpler.

Simple enough for Claude to track down. Fixed. It is indeed (only) related to reloading static code that could find stale clauses through the old index.

---

<div class="post-metadata">

**Author:** ![stassa.p](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/stassa.p/32/712_2.png) [@stassa.p](https://swi-prolog.discourse.group/u/stassa.p)\
**Post date:** [October 13, 2026, 12:08pm UTC](https://swi-prolog.discourse.group/t/possible-database-update-problem/9862/4 "2026-10-13T12:08:51Z")

</div>

Wonerful! I’ll get the next daily build then. Thank you @Jan and Claude.
