I have defined list of doors in rooms:
class facts
door : (string Room1, string Room2).
skarb : (string Skarb, string Room).
class predicates
go : (string Room1, string Room2, string* R_list) nondeterm anyflow.
is_Member : (string Room, string* R_list) nondeterm .
write_list : (string* R_list) nondeterm .
clauses
door("a", "b").
door("b", "e").
door("b", "c").
door("d", "e").
door("c", "d").
door("e", "f").
door("g", "e").
door("g", "a").
door("h", "b").
door("h", "a").
door("h", "f").
door("i", "b").
door("i", "h").
door("i", "c").
door("i", "k").
skarb("bomba", "d").
And some Predicates:
go(Room, Room, R_list) :- stdio::write("\n\nJest droga:"), write_list(R_list), !.
go(Room1, Room2, R_list) :- door(Room1, X), not(is_Member(X, R_list)), go(X, Room2, [X | R_list]).
go(Room1, Room2, R_list) :- door(X, Room1), not(is_Member(X, R_list)), go(Room2, X, [X | R_list]).
is_Member(Room, [Room | _]) :- !. is_Member(Room, [_ | Tail]) :- is_Member(Room, Tail).
write_list([]) :- !.
write_list([Head | Tail]) :- stdio::write( Head), write_list(Tail).
And I'm looking for a way from room to room:
run():-
stdio::write("\nDroga z a do f"),
R_list=["a"],
go("a", "f", R_list),
fail.
This predicate works and return:
Jest droga:feba
Jest droga:fedcba
Which is list of rooms, that I must pass the from a to f. run():- stdio::write("\nDroga z f do a"), R_list=["f"], go("f", "a", R_list), fail. But this one, returns nothing. And As you may notice it's just reverse of the previous case.
This question smells a lot like homework. You should tag it appropriately.
door(A, B)
here is a directed edge from A
to B
door(A, B)
in your definition does not also imply door(B, A)
In fact, f doesn't lead to any other rooms. It's a dead end, more or less.
Disclaimer: I'm not sure if there's a better way than the way I'm suggesting.
Also, I'm not positively sure path
is written correctly, as I can't test it right now.
You could build a new rule like so:
reversible_door(A,B):- door(A,B).
reversible_door(A,B):- door(B,A).
But you still have to watch out for cycles. You can avoid cycles by tracking visited rooms.
path(A,B,_):- reversible_door(A,B).
path(A,B,Nodes):- reversible_door(A,X),
not(member(X,Nodes)),
path(X,B,[A|Nodes]).
Of course, this is also assuming there are no self edges, like door(A, A).
If that's already implied, great. But you can also check for that, if you wanted to.
This isn't directly related to the question, but you can check if a room has a 'bomba' with not(skarb("bomba",A))