I am trying to write a simple prolog rule that checks if a given person from a database has ever sent or received a message to or from another person in that database. The fact is based in the form of message(sender, receiver, date). The code I have is;
?-message(max, X, Y) ; message(A, max, B).
The problem is, only the first combination of the OR alternative ";" is tried, and I receive that values of X and Y, But the program stops there without executing the second combination of the OR alternative, and i receive no values for A and B. I just need some advice to know if I am going about this the wrong way. Thanks.
As soon as the first message matches, your rule is satisfied; it would only need to consider the second message if the first failed. If you want both to be used, you want an and (, instead of ;).
The disjunction pushes a choice point to the query. To explore all choice points, you can do two things:
;
, or SPACE, or TAB. findall/3
or bagof/3
. For example, with these messages defined:
message(max, fred, 3).
message(max, fred, 4).
message(fred, max, 1).
message(fred, scott, 2).
message(max, scott, 5).
And your query, and backtracking:
?- message(max, To, Time) ; message(From, max, Time).
To = fred,
Time = 3 ;
To = fred,
Time = 4 ;
To = scott,
Time = 5 ;
Time = 1,
From = fred.
Keep in mind that your query is more or less the same as a predicate:
person_message(From, to(To, Time)) :-
message(From, To, Time).
person_message(To, from(From, Time)) :-
message(From, To, Time).
With this defined:
?- person_message(max, M).
M = to(fred, 3) ;
M = to(fred, 4) ;
M = to(scott, 5) ;
M = from(fred, 1).
?- bagof(M, person_message(max, M), Message).
Message = [to(fred, 3), to(fred, 4), to(scott, 5), from(fred, 1)].
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.