views:

71

answers:

3
emissionOf(alpha).
emissionOf(beta).

detected(proton), detected(electron) :- emissionOf(alpha), emissionOf(beta).

I'm facing the problem that for some (probably obvious) reason Prolog doesn't accept the last line of the above code. The reason has something to do with:

detected(proton), detected(electron)

If I try just

detected(proton)

it behaves correctly.

What is the problem? I am trying to state that if there is both emission of alpha and beta, then there there are detections of both protons and electrons.

Thanks

A: 

From what was told to me, it is inherent to Prolog's algorithm. Each stated sentence must be a Horn clause.

devoured elysium
+4  A: 

You are correct, clauses in PROLOG are Horn clauses. Furthermore, it so happens that a conjunction in the head of a clause such as:

detected(proton), detected(electron) :- emissionOf(alpha), emissionOf(beta).

...(which is not a Horn clause) is in fact equivalent to the following two separate Horn clauses:

detected(proton) :- emissionOf(alpha), emissionOf(beta).
detected(electron) :- emissionOf(alpha), emissionOf(beta).

...since both facts detected(proton) and detected(electron) are implied by the conjunction of the body goals.

Note that there may be several other equivalent ways to encode what you intend the program to mean, such as the following (as an example):

emissionOf(alpha).
emissionOf(beta).

detected(X) :- 
  emissionOf(alpha), 
  emissionOf(beta), 
  (X = proton; X = electron).

Executing goal detected(X) will bind X to atom proton, then to electron on backtracking.

sharky
+1  A: 

It's equivalent to

,(detected(proton),detected(electron)) :- emissionOf(alpha), emissionOf(beta).

You are essentially trying to redefine the ,/2 operator, which is not allowed. What error message did you get?

What is it you are trying to say? That both detected(proton) and detected(electron) are true if emissionOf(alpha) and emissionOf(beta) are true? In that case you need to split in into two clauses as @sharky said:

detected(proton) :- emissionOf(alpha), emissionOf(beta).
detected(electron) :- emissionOf(alpha), emissionOf(beta).

This will give you both solutions on backtracking. I think this is definitely clearer then his second suggestion.

rvirding