I am trying to save an initial state of the prolog KB and then read it back on demand.
I am using write_canonical to write predicates to an output stream, and later i am using consult/1 to read the file back. However, i then get the error above for pred/2.
pred/2 is defined as dynamic.
the write and read occurs in a module by use of an exported write_kb and read_kb predicate.
Before those predicates are read in, you need to declare them as dynamic. Typically you would in a source file write
:- dynamic pred/2.
But this should be in the file you are calling consult/1 on.
Your issue may have come because you made your declaration elsewhere, as pred/2 may have been set as dynamic, but module_x::pred/2 is a distinct predicate in a different module. These must match.
I have some facts, created with format(Stream, ~q.~n, [Fact]), which I load with ensure_loaded/1, and it works fine. (I don’t have any dynamic declarations, either.)
Indeed. It of course all depends on whether the predicate that is defined in the file is already defined in the system and how, including how it is loaded and whether and what header is added to the file with facts. We do not know that. please include details if you want advice!
In general, if you want to load a large number of (dynamic) facts from a file, a read/assert loop is not a bad idea. It bypasses all the administration and analysis done by the normal compiler and, if you are dealing with possibly non-trusted data, allows you to check the shape of the data and avoid executing possibly malicious goals from directives.