Expert Systems in Prolog: Good Practices

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?

Thank you!

1 Like

Asserting facts is still perfectly reasonable. What’s evolved is the indexing of those facts: SWI-Prolog -- Just-in-time clause indexing

… plus dictionaries as a datatype, to hold structured data: SWI-Prolog -- Dicts: structures with named arguments

Any specifics on what you’re interested in?

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 :frowning: 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 :slight_smile: