3

I have a fact:

loves(romeo, juliet).

then i have an 'or' rule:

dances(juliet) :- loves(romeo, juliet).
dances(juliet) :- dancer(juliet).

As you can see dancer fact does not exist but this should be no problem and dances(juliet) should return me true. Instead it returns me true and then throws an exsitence exception about dancer fact. Is there a way to write rules for non existent facts or rules? Do I need to check if the fact exists?

Laimonas Sutkus
  • 3,247
  • 2
  • 26
  • 47

3 Answers3

5

To achieve "failure if not existant", you can declare your predicate dynamic using the directive dynamic/1.

For example:

:- dynamic dancer/1.

If you add this directive to your program, you get:

?- dances(X).
X = juliet .

and no errors.

mat
  • 40,498
  • 3
  • 51
  • 78
3

As far as I know there is not a way to use a nonexistant predicate. You could either check if the rule exists using the methods described in this question or you could just have some sort of placeholder to make sure that it does exist. A rule doesn't seem very useful if it is always false, so just write a couple of the true cases before you use it.

dancer(someone). %% To make sure that fact exists 

loves(romeo, juliet).
dances(juliet) :- loves(romeo, juliet).
dances(juliet) :- exists(dancer), dancer(juliet).
Community
  • 1
  • 1
qfwfq
  • 2,416
  • 1
  • 17
  • 30
1

Technically, you could do something like this:

dances(juliet) :- catch(dancer(juliet), 
                        error(existence_error(procedure, dancer/1), _),
                        false
                  ).

Which will run dancer(juliet) if the predicate exists, fail if it doesn't, and error otherwise.

I wouldn't say this is a very advisable thing to do though.

Fatalize
  • 3,513
  • 15
  • 25