2
votes

I've got a problem with Prolog. I'm currently trying to take a Prolog tutorial and I'm stuck with the recursion. Despite doing everything as I've been told, I don't get the correct results. I also can't find the mistake Ive made..

First, here is the link to the tutorial.

And now here is my problem. I've got the following code: (I spared out the rest since it doesn't matter for this problem)

location(desk, office).
location(apple, kitchen).
location(flashlight, desk).
location('washing machine', cellar).
location(nani, 'washing machine').
location(broccoli, kitchen).
location(crackers, kitchen).
location(computer, office).
location(envelope, desk).
location(stamp, envelope).
location(key, envelope).

is_contained_in(T1,T2):-
  location(X,T2),
  is_contained_in(T1,X).

Now it is expected, that requesting is_contained_in(X, office). should give me a list of all the things that are in the office or inside things within the office. Also requesting is_contained_in(key, office). should be true. But the result is always just false (no list and nothing, just false), no matter what I try.

I also tried changing the recursion predicate to the following:

is_contained_in(T1,T2):-
  location(X,T2),
  write(X), nl,
  is_contained_in(T1,X).

Prolog will actually write down all the things that are in the office and the false afterwards. The recursion loop apparently does work. But I just can't figure out why it doesn't work with queries such as is_contained_in(key, office).. He does realize that T1 is key at some point in the loop, but it still won't write true in the end.

I'm sorry if my English isn't that great. I just hope you understand my problem and that you can help me! :)

Regards

1
Okay.. I've found a solution for my problem.. I can use: is_contained_in(T1,T2) :- location(T1,T2). is_contained_in(T1,T2) :- location(X,T2), is_located_in(T1,X). But I would still be really glad if someone could explain me, why the example given in the tutorial (which I wrote in the original post) does not work. I don't understand it. :(dendelyne
what you had, being just one rule, had no "or" in it. Now, with the two rules, you got your "or".Will Ness

1 Answers

2
votes

Like in the imperative programming, recursion is defined by two properties:
1- A simple base case (or cases).
2- A set of rules that reduce all other cases toward the base case.
In your case, you didn't define your base case, in this particular problem is that an Object "is contained in" a Location if there is a fact location(Object, Location) in your knowledge base (program).
This is solved by adding a clause is_contained_in/2 to your predicate, that represents the base case:

is_contained_in(T1,T2):-      % Base case
  location(T1,T2).
is_contained_in(T1,T2):-      % General rule
  location(X,T2),
  write(X), nl,
  is_contained_in(T1,X).

Test:

?- is_contained_in(key,office).
true.

?- is_contained_in(Object,office).  
Object = desk ;  
Object = computer ;  
Object = flashlight ;  
Object = envelope ;  
Object = stamp ;  
Object = key ;  
false.