It’s very quiet here today, so let me give you a couple of problems to chew on.
As seen earlier here, by means of the thread_*
predicates it’s often possible and indeed fairly easy to translate an Erlang program into a functionally equivalent Prolog program. But is it always possible/easy?
Here’s another Erlang example, this time an implementation of a kind of priority queue from a very nice and free introduction to Erlang:
important() ->
receive
{Priority, Message} when Priority > 10 ->
[Message | important()]
after 0 ->
normal()
end.
normal() ->
receive
{_, Message} ->
[Message | normal()]
after 0 ->
[]
end.
The idea is that calling important/1
will build a list of all messages with those with a priority above 10 coming first.
Here’s how it can be programmed in Web Prolog:
important(Messages) :-
receive({
Priority-Message when Priority > 10 ->
Messages = [Message|MoreMessages],
important(MoreMessages)
},[
timeout(0),
on_timeout(normal(Messages))
]).
normal(Messages) :-
receive({
_-Message ->
Messages = [Message|MoreMessages],
normal(MoreMessages)
},[
timeout(0),
on_timeout(Messages = [])
]).
and here’s how it runs:
?- self(S), S ! 15-high, S ! 7-low, S ! 1-low, S ! 17-high.
S = 45783241@'http://localhost:3060'.
?- important(Messages).
Messages = [high,high,low,low].
Problem 1
How would you program this example using suitable thread_*
predicates?
Here’s how you should be able to test your solution:
?- thread_self(S),
thread_send_message(S, 15-high),
thread_send_message(S, 7-low),
thread_send_message(S, 1-low),
thread_send_message(S, 17-high).
S = main.
?- important(Messages).
Messages = [high,high,low,low].
Problem 2
Informed by your solution to Problem 1, how would you implement the receive/1-2
predicate so that it can handle this example (and other examples involving receive/1-2
)?
Problem 3
Does this example show that Erlangs receive/1-2
is more expressive/powerful than the thread_get_message/1-3
predicate that SWI-Prolog and (other Prolog systems) offer?
My own conclusions so far
I have failed to find a neat solution to Problem 1. I hope that someone will be able to show me how to do it!
I have a couple of solutions to Problem 2, but they’re more hacky than I’d like.
My answer to the question in Problem 3 is yes. I think so. Can you prove me wrong?