Swipl's nagging for dynamic assertions that'll never exist

swipl keeps nagging me with warnings to declare predicates as dynamic, how do I tell it to quit with the warnings?

These warning are either for operators or predicates that are never called and will never exist. The origin files for the warnings have no business knowing how these terms will be manipulated, they’re just arguments for other predicates elsewhere to deal with. The huge warning outputs on a make. for these predicates are hiding more important information higher up, so I want to turn it off.

Is it possible to give us a small example of code that’s triggering those warnings? Curious…

I tried, but was having great difficulty replicating it. This is in my PhD project so unfortunately I can’t share it either. To give an idea though, my structure is:

webapp
    | server.pl  % calls loader, runs setup and serves
    | loader.pl  % setup handles file search paths, imports all modules for a quick test, mounts databases
    | kb
        | kb.pl   % public interface to kb
        | query.pl % query predicates
        | actions.pl % for updating situations
        | fluents.pl % dynamic values determined from the situation data structure
        | situation_manager % (persistency, golog)
    | webapp
        | api_routes.pl % http:handlers
        | api_controllers.pl % the predicates called by http:handler, sorts out methods and parameters as well as what to reply with.
        | api_models.pl % interactions with the kb, mostly queries

So my api_models.pl will send a query to the kb that uses some fluent or action, which is a compound term in the query predicate. query.pl will use the other modules in kb to manipulate that compound term into something that can be answered, which involves adding the situation to the term and searching the situation for a valid response.

Trouble is, swipl is saying api_models.pl is referencing for example hasColour/2 and asking me to declare it as dynamic. In api_models.pl this would be something like: query(hasColour(Thing, Colour)). But hasColour/2 is going to be called in a holds(hasColour(Thing, Colour), Situation) predicate that’ll end up looking for paint(Thing, Colour) in the user’s Situation structure (it’s an API), before calling hasColour(Thing, Colour, s0) for the default value. hasColour/2 doesn’t exist and can never exist by the philosophy underpinning the implementation.

The end of make/0 looks like this:

    (   prolog:make_hook(after, Reload)
    ->  true
    ;   list_undefined,
        list_void_declarations
    ).

So, define prolog:make_hook/2. Reload is a list of files that have been reloaded.

Except for working on an external program that has lots of dead code and undefined predicates you do not want to fix, I’d not silence those warnings …

Thank you! For a temporary turn off, I just did this in the repl:

?- dynamic check:list_undefined.
?- retractall(check:list_undefined).
?- assertz(check:list_undefined).

I can have peace when I want it, and restart the repl and it’ll be back to normal.

That is rather hacky :slight_smile: I’d go for

:- multifile prolog:make_hook/2.

prolog:make_hook(after, _).

That way you can still call the check predicates.

1 Like

Your example suggests that SWI-Prolog considers query/1 a meta-predicate. Is that the case?

Not really, what is passed to query/1 isn’t ever called, it’s manipulated. So arguments are extracted from it and searched for in another data-structure. There’s also reasoning between the query and search, so if I query(asserted(S, P, O)) then I’ll search for an ‘event’ that asserts P(S, O) or retracts it in the situation → asserted(S, P, O, Sit). The ‘event’ won’t unify with the thing being searched, one event can change multiple fluents.

If I query(fact(S, P, O))fact(S, P, O, Sit), then I’ll throw my full arsenal of ontological reasoning at that, checking if P is transitive, symmetric or reflexive, inheriting values, and running rules of equivalency, all of which search the situation through their own queries. Tabling is nice here!

Furthermore, a query can contain a logical expression, like query(F & B v C -> some(var, D)). The kb is basically an ontology authoring tool with reasoning through queries.