views:

488

answers:

2

I'm working on a college assignment where I must verify if a certain clause (as a fact or as a rule) exists in the current clause database.

The idea is to use a rule whose head is verify(+name, +arguments). This rule should be true if in the database exists another rule whose head is name(arguments)

Any help would be greatly appreciated...

+1  A: 

Are you familiar with the concept of unification? What you have to do is: just call a predicate that looks like the one you're trying to find.

So, say in your database is:

father(abraham,isaac).

Now you want to call something like:

verify(father,[abraham,isaac]).

Your predicate body will then have to contain a mechanism of calling father(abraham,isaac). which should then return true. Calling father(abraham,adam) should fail.

You will need two predicates for this: =../2 and call/2. If you are using SWI-Prolog, call help(=..). and help(call) from the interpreter's command line to access the documentation.

I hope I didn't spoil the assignment for you. You still have to find out what to do with partially instantiated predicates (so, say something like verify(father,[abraham,X]). on your own, but it shouldn't be hard from here.

Good luck.

Aleksandar Dimitrov
+1  A: 

Using call/1 is not a good idea because call/1 actually calls the goal, but you just want to find out if the fact/rule exists, and you don't want to wait after a long calculation that the call might trigger, and you don't want to have something printed on the screen if the called rule in turn calls e.g. writeln/1. In addition, you would want verify/2 to succeed even if the call failed (but the fact/rule is otherwise there).

As a solution, SWI-Prolog offers callable/1

callable(+Term)

True if Term is bound to an atom or a compound term,
so it can be handed without type-error to call/1, functor/3 and =../2.

Here are two version of verify/2, one using call/1 and the other using callable/1.

verify1(Name, Arguments) :-
    Term =.. [Name | Arguments],
    call(Term).

verify2(Name, Arguments) :-
    Term =.. [Name | Arguments],
    callable(Term).

father(abraham, isaac) :-
    writeln('hello').

father(abraham, adam) :-
    fail.
Kaarel