Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swi-Prolog: No permission to modify static procedure

Tags:

prolog

I'm a prolog beginner. I would really appreciate any help for compiling this example. I guess rules are in the form "consequent :- antecedent"

%rules
prey(Y2), watch(X2,Y2) :- predator(X2).
false :- predator(X1),prey(Y1),intelligent(Y1),watch(X1,Y1),catch(X1,Y1).
catch(X3,Y3);hungry(X3) :- predator(X3),prey(Y3),watch(X3,Y3).

%facts
predator(shaki).
prey(pelusa).
intelligent(shaki).
intelligent(pelusa).
watch(shaki,pelusa).

I compiled the code using SWI-Prolog version 5.10.4 (i386, Ubuntu Natty Narwhal):

swipl -s "pathofthecode.pl"

Swi-Prolog threw this error for the second rule:

'$record_clause'/2: No permission to modify static_procedure `(;)/2'

Thanks azhrei, you said: " I think what you're trying to say is X1 will not be able to catch Y1, even though X1 is a predator watching the prey Y1, because Y1 is intelligent.", yes it is!!

I found that prolog has some strong constrains [1]:

  1. Prolog doesn't allow "or" (disjunctive) facts or conclusions.
  2. Prolog doesn't allow "not" (negative) facts or conclusions.
  3. Prolog doesn't allow most facts or conclusions having existential quantification.
  4. Prolog doesn't directly allow second-order logic.

So I changed the code like so:

%rules
predator(X) :- prey(Y), watch(X,Y).
catch(X,Y) :- predator(X),prey(Y),not(intelligent(Y)),watch(X,Y).
hungry(X) :- predator(X),prey(Y),watch(X,Y),not(catch(X,Y)).

%facts
prey(pelusa).
intelligent(shaki).
intelligent(pelusa).
watch(shaki,pelusa).

I also tried using:

 false :- predator(X),prey(Y),intelligent(Y),watch(X,Y),catch(X,Y).

And it compiles, but when prolog needs to find whether catch(X,Y) is true or not, it can't because the predicate isn't in a rule consequent.

--

[1]. Neil C. Rowe, URL:http://faculty.nps.edu/ncrowe/book/chap14.html

Note: this example was taken from professor Yadira Solano course at UCR, Costa Rica

like image 245
JMFS Avatar asked Jul 19 '12 04:07

JMFS


1 Answers

The error message is about your usage of the semi-colon, ;. You can't redefine it.

You can't change the false predicate either. So I'm surprised that you say this compiles:

false :- predator(X),prey(Y),intelligent(Y),watch(X,Y),catch(X,Y).

It doesn't compile for me. :-) (SWI-Prolog)

In the second rule, I think you're trying to say is: X1 will not be able to catch Y1, even though X1 is a predator watching the prey Y1, because Y1 is intelligent. In that case you would need:

catch(X,Y) :- ...,...,...,...,not(intelligent(Y)).

(As you found yourself, and edited in your post. :-)

Note: The link you provided shows some statements which are logically equivalent but that doesn't mean you can use them in code, because they are not procedurally equivalent in Prolog. You can use false and ; in your queries (at the prolog prompt), or in rule bodies, but not in rule heads.

like image 139
azhrei Avatar answered Sep 30 '22 07:09

azhrei