Prolog unknowns in the knowledge base

438 views Asked by At

I am trying to learn Prolog and it seems the completeness of the knowledge is very important because obviously if the knowledge base does not have the fact, or the fact is incorrect, it will affect the query results. I am wondering how best to handle unknown details of a fact. For example,

%life(<name>,<birth year>,<death year>)
%ruler(<name>,<precededBy>,<succeededBy>)

Some people I add to the knowledge base would still be alive, therefore their year of death is not known. In the example of rulers, the first ruler did not have a predecessor and the current ruler does not have a successor. In the event that there are these unknowns should I put some kind of unknown flag value or can the detail be left out. In the case of the ruler, not knowing the predecessor would the fact look like this?

ruler(great_ruler,,second_ruler).
1

There are 1 answers

2
Daniel Lyons On BEST ANSWER

Well, you have a few options.

In this particular case, I would question your design. Rather than putting both previous and next on the ruler, you could just put next and use a rule to find the previous:

ruler(great_ruler, second_ruler).
ruler(second_ruler, third_ruler).

previous(Ruler, Previous) :- ruler(Previous, Ruler).

This predicate will simply fail for great_ruler, which is probably appropriate—there wasn't anyone before them, after all.

In other cases, it may not be straightforward. So you have to decide if you want to make an explicit value for unknown or use a variable. Basically, do you want to do this:

ruler(great_ruler, unknown, second_ruler).

or do you want to do this:

ruler(great_ruler, _, second_ruler).

In the first case, you might get spurious answers featuring unknown, unless you write some custom logic to catch it. But I actually think the second case is worse, because that empty variable will unify with anything, so lots of queries will produce weird results:

ruler(_, SucceededHimself, SucceededHimself)

will succeed, for instance, unifying SucceededHimself = second_ruler, which probably isn't what you want. You can check for variables using var/1 and ground/1, but at that point you're tampering with Prolog's search and it's going to get more complex. So a blank variable is not as much like NULL in SQL as you might want it to be.

In summary:

  • prefer representations that do not lead to this problem
  • if forced, use a special value