Does a rule without passing a variable against the philosophy of declarative programming or prolog?

Viewed 78
cancer():-
   pain(strong),
   mood(depressed),
   fever(mild),
   bowel(bloody),
   miscellaneous(giddy).

diagnose():-
   nl,
   cancer()->write("has cancer").

for example, dog(X) says that X is a dog but my cancer statement just checks whether the following conditions meet. Is there a better way to do that?

2 Answers

In pure Prolog, a predicate without any arguments can only succeed or fail (or not terminate at all).

Thus, it can encode only very little information. A predicate that always succeeds is already available: true/0, having zero arguments. A predicate that always fails is also already available: false/0, also having zero arguments. A predicate that never terminates can be easily constructed.

So, in this sense, you do not need more predicates with zero arguments, and I think you are perfectly justified in being suspicous about such predicates.

Predicates with zero arguments are of limited use since they are so specific. They may however be used for example to describe a fixed set of tests, or be useful only for their side-effects. This is also what you are using, by emitting output on the terminal in case the predicate succeeds.

This means that you are leaving the pure subset of Prolog, and now relying on features that are beyond pure logic.

This is typically a very bad idea, because it:

  • prevents or at least complicates many forms of reasoning about your program
  • makes it much harder to test your predicates
  • is not thread safe in general
  • etc.

Therefore, suppose your write your program as follows:

cancer(Patient):-
        patient_pain(Patient, strong),
        patient_mood(Patient, depressed),
        patient_fever(Patient, mild),
        patient_bowel(Patient, bloody),
        patient_miscellaneous(Patient, giddy).

This predicate is now parametrized by a patient, and thus significantly more general than what you have posted.

It can now be used to reason about several patients, it can be used to reason in parallel about different patients, you can use a Prolog query to test the predicate etc.

You can further generalize the predicate by defining for example patient_diagnosis/2, keeping everything completely pure and benefiting from the above advantages. Note that a patient may have several illnesses, which can be emitted on backtracking.

Thus: Yes, a rule without arguments is at least suspicious and atypical if it arises in your actual code. Leaving aside scenarios such as "test case" and "consistency check", it can only be useful for its side-effects, and I recommend you avoid side-effects if you can.

For more information about this topic, see .

cancer() isn't legal syntax, but the idea's perfectly fine.

Just do the call as

cancer

and define it as a fact or rule.

cancer.   % fact

cancer :- blah blah  %rule

in fact, you use a system predicate with no args in your program -

nl is a predicate that always succeeds, and prints a newline.

There are many reasons to have a predicate with no arguments. Suppose you have a server that runs in a slightly different configuration in production than in development. Developer access API is off in production.

my_handler(Request) :-
      development,
      blah blah

development only succeeds if we're in development environment

or you might have a side effect set off, or be using state.

Related