In David Merritt’s book “Building Expert Systems in Prolog,” he suggests storing the values of answered questions in a “known” predicate like this:
ask(A, V):-
known(yes, A, V), % succeed if true
!. % stop looking
ask(A, V):-
known(_, A, V), % fail if false
!,
fail.
ask(A, V):-
write(A:V), % ask user
write('? : '),
read(Y), % get the answer
asserta(known(Y, A, V)), % remember it
Y == yes. % succeed or fail
Is this still a recommended approach these days? Or are people using tabling, or storing state in some other way?
Is there an example of a relatively modern expert system in Prolog that is considered to be well-designed and that I could use as an example?
For large sets of key-value pairs, I’ve found rbtrees or AVL trees to be faster … library(rbtrees), library(assoc), and dicts all have different interfaces, so I wrote a small abstraction layer to allow changing which one I was using when I was experimenting with which was faster for my application (which was essentially large symbol tables).
One advantage of using a data structure instead of assert/retract is that I can do parallel computations without worrying about global data. I used pack(edcg) to automatically add the key-value pairs to my calls, which avoided having unwieldy long parameter lists.
There is also thread_local/1 as alternative to dynamic/1. Probably that should have been the default, as XSB chose to do But still, using a data structure should probably the first thing to consider for almost any task that involves state. And sometimes using the dynamic database is the best option