Question

I have a problem with defining procedures in Prolog. I have two source files and want to consult Prolog engine with both of them. This can be done by invoking Prolog as swipl -g “['1.pl','2.pl'].

Both of the files are generated by another program written in another programming language and i can't predict the exact content of the files beforehand.

The problem is that in one of the files there is always a rule

predicate1(X):-predicate2(X).

But,sometimes the rule

predicate2(something):-body

does not exist in both of the files and i get a error "predicate2" is undefined, when executing some queries for predicate1.

If i include the line

:- dynamic(predicate2/2). 

into one of the files it only helps if predicate/2 is not defined in another file (otherwise i get something like "are you really sure you want to redefine the predicate2/2?". And here i don't want to redefine something to save the data from another file.

So,i have no idea how to make the predicate just "defined". I need a solution for SWI-Prolog or SICStus Prolog. (unfortunately the versions do not have a section for defining predicates,like visual Prolog)

Was it helpful?

Solution

In SWI Prolog you can avoid the error. Change the system behaviour using the ISO builtin

:- set_prolog_flag(unknown, Choice).

The Choice is one of (fail,warning,error).

So your command line will be:

swipl -g “set_prolog_flag(unknown,fail),['1.pl','2.pl']."

Another possibility: define a fake procedure

swipl -g “assert(predicate2(_):-fail),['1.pl','2.pl']."

HTH

OTHER TIPS

You need to declare predicate2/2 multifile with the ISO directive of same name. So in each of the files, you write at the top, or prior to any clauses of predicate2/2:

:- multifile(predicate2/2).

This, regardless of whether or not you are having clauses for that predicate.


The suggestion by @CapelliC is definitely a dangerous move. If you turn off all existence errors you will miss many legitimate errors!

For example, you declared dynamic(predicate2/2) but used predicate2(_). So which arity do you want?

Clearly, Prolog is not able to answer any question we formulate. For instance, if we ask if Donald is a duck

?- isDuck(Donald) .
! ----------------------------------------
! Error 20 : Predicate Not Defined
! Goal : isDuck(_17610)

Prolog will answer that it does not know anything about if “something” is or is not a duck. What it is happening is that the logic predicate isDuck/1 is not defined (Predicate Not Defined), so Prolog is not able to check if “something” is or is not a duck. As we will see later, even if Prolog does not know what a duck is, it is possible to teach it how to distinguish between what is a duck and what it is not. As we said previously, Prolog is a dialogue language. In the dialogue between the system and the programmer Prolog is not only able to answer certain questions, but is also able to learn about what it does not know. To answer the questions formulated by the programmer, Prolog checks a knowledge base where everything is registered that Prolog knows. In the beginning of the Prolog session, the knowledge base keep a basic knowledge that includes, between other things, concepts and definitions of natural number’s arithmetic. During the session it is possible to increase this knowledge base, including definitions and concepts that Prolog isn't familiar with (for instance the definition of a duck), or also modifying and extending definitions that Prolog knows (for instance, including new arithmetic operators for natural numbers). Facts and rules express the knowledge base. Facts and rules are syntactic representations of the first order Horn Clauses. So all the Prolog’s knowledge is expressed using (almost) exclusively first order logic. This is the reason why Prolog is said to be a logic language. A program in Prolog is a set of facts and rules that express certain knowledge.


Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top