0

I'm learning Constraint Handling Rules (in SWI-Prolog) and trying to (faithfully) program the "Example 5 (Petri Nets - Barber Shop)" from https://www.informatik.uni-ulm.de/pm/fileadmin/pm/home/fruehwirth/rule-based-summer-2013.pdf (page 10).

Exercise 5 (Petri Nets - Barber Shop). A typical scenario at a Barber shop is as follows:
Customers enter a Barber shop and wait till a barber is idle and ready to serve them. Then
the barber cuts the hair of a customer. When the hair cut is done, the customer leaves and the
barber becomes idle once again. This can be represented using the Petri net given below:

   customers waiting   cut 
       O   -------------> ___              ____
                         |   | -->   O --> |   |  --->  customers done
       O   ------------->|___|   customers |___|  ---- 
   idle barbers                  cutting   leave      |
       ^---------------------------------------------<

Translate the Barber shop Petri net into CHR by adding the constraints customers_waiting/0,
idle_barbers/0, customers_cutting/0, and customers_done/0 for each of the places. Add
an observer/0 constraint to print the interesting states of the problem. A typical test 
query would be ?-observer,customers_waiting,customers_waiting,idle_barbers.

What I wonder is how to program the observer/0 constraint in CHR. I've tried to figure out if observer has a special meaning in Petri Nets, but haven't found any indication of that. If observer refers to the Observer Pattern then I would expect that it should be observer/1 instead, but perhaps there's a CHR trick that one can use?

Here's the code I've done. Using the state/1 is probably considered cheating, but it's a way to collect the states of the flow. (For debugging purposes, I also added the constraints with writeln/1).

:- use_module(library(chr)).

:- chr_constraint customers_waiting/0, idle_barbers/0, customers_cutting/0, 
customers_done/0, observer/0, states/1.


go :-
    observer,customers_waiting,customers_waiting,idle_barbers,nl.

% This is probably not the intended idea of using the observer/0.
observer <=> states([]).


idle_barbers ==> writeln(idle_barbers) .
customers_waiting ==> writeln(customers_waiting).
customers_cutting ==> writeln(customers_cutting).
customers_done ==> writeln(customers_done).
    
customers_waiting, idle_barbers, states(States) <=> 
    append(States,[customers_waiting,idle_barbers],NewStates) | customers_cutting, states(NewStates).

customers_cutting, states(States) <=> 
   append(States,[customers_cutting],NewStates)| states(NewStates), customers_done.

customers_done, states(States) <=> 
    append(States,[customers_done],NewStates) | states(NewStates), idle_barbers.

Running the program:

$ swipl petri_nets_barber_shop.pl
?- go.
customers_waiting
customers_waiting
idle_barbers
customers_cutting
customers_done
idle_barbers
customers_cutting
customers_done
idle_barbers

idle_barbers,
states([customers_waiting, idle_barbers, customers_cutting, customers_done, customers_waiting, idle_barbers, customers_cutting, customers_done]).

The output before the newline is from writeln/1, and the two lines after are from CHR's constraint store.

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
hakank
  • 6,629
  • 1
  • 17
  • 27

0 Answers0