# Expert Systems in Prolog: Good Practices

**URL:** <https://swi-prolog.discourse.group/t/expert-systems-in-prolog-good-practices/7611>\
**Category:** General\
**Created:** [July 20, 2024, 2:05pm UTC](https://swi-prolog.discourse.group/t/expert-systems-in-prolog-good-practices/7611 "2024-07-20T14:05:08Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![sledov](https://avatars.discourse-cdn.com/v4/letter/s/bb73d2/32.png) [@sledov](https://swi-prolog.discourse.group/u/sledov)\
**Post date:** [July 20, 2024, 2:05pm UTC](https://swi-prolog.discourse.group/t/expert-systems-in-prolog-good-practices/7611/1 "2024-07-20T14:05:08Z")

</div>

In David Merritt’s book “Building Expert Systems in Prolog,” he suggests storing the values of answered questions in a “known” predicate like this:

```prolog
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!

---

<div class="post-metadata">

**Author:** ![brebs](https://avatars.discourse-cdn.com/v4/letter/b/e9c0ed/32.png) [@brebs](https://swi-prolog.discourse.group/u/brebs)\
**Post date:** [July 20, 2024, 8:14pm UTC](https://swi-prolog.discourse.group/t/expert-systems-in-prolog-good-practices/7611/2 "2024-07-20T20:14:32Z")

</div>

Asserting facts is still perfectly reasonable. What’s evolved is the indexing of those facts: [SWI-Prolog -- Just-in-time clause indexing](https://www.swi-prolog.org/pldoc/man?section=jitindex)

… plus dictionaries as a datatype, to hold structured data: [SWI-Prolog -- Dicts: structures with named arguments](https://www.swi-prolog.org/pldoc/man?section=bidicts)

Any specifics on what you’re interested in?

---

<div class="post-metadata">

**Author:** ![peter.ludemann](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/peter.ludemann/32/48_2.png) [@peter.ludemann](https://swi-prolog.discourse.group/u/peter.ludemann)\
**Post date:** [July 20, 2024, 10:38pm UTC](https://swi-prolog.discourse.group/t/expert-systems-in-prolog-good-practices/7611/3 "2024-07-20T22:38:26Z")

</div>

> [@brebs](#):
>
> dictionaries as a datatype, to hold structured data

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.

---

<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:** [July 22, 2024, 8:47am UTC](https://swi-prolog.discourse.group/t/expert-systems-in-prolog-good-practices/7611/4 "2024-07-22T08:47:29Z")

</div>

> [@peter.ludemann](#):
>
> One advantage of using a data structure instead of assert/retract is that I can do parallel computations without worrying about global data.

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 🙂
