Travel in both ways

In previous lessons, the interconnections between two stations were oriented in only one direction. In real life, the customers can travel in both directions in the metro: if a line exists between station X and station Y, people can travel both ways, from station X to station Y or from station Y to station X.

To enable travels in both directions, we are going to adapt the init.ls script to populate the Connection bag with new initial resources which mirror the previously defined interconnections.

Updating init.ls script

During the initialization phase of the application, we add new resources in the Connection bag. "Mirror" resources are added to enable "backward" travel.

Of course, the color associated with a Connection resource is the same for both travel directions.

 ::
 {
 ["Metro","Connection"].put("red","A","B") ;
 ["Metro","Connection"].put("lightblue","A","D") ;
 ["Metro","Connection"].put("yellow","C","D") ;
 ["Metro","Connection"].put("red","B","A") ;         <--\
 ["Metro","Connection"].put("lightblue","D","A") ;   <----- : New resources
 ["Metro","Connection"].put("yellow","D","C")        <--/
 }.

2-hop travel

Without traveling both ways and with our initial network (without the ("B", "D") Connection), Bob could not reach his intended "D" Destination.

Now that both ways are enabled, a new ("B", "A") resource exists. This means that, if Bob could change line during his travel, he could reach his intended "D" Destination by traveling :

  • first : from "B" to "A"
  • then : from "A" to "D"

This can be done by adding a new application rule in the trom.ls script :

Updating our application script: trom.ls

Within the new version of the trom.ls application script, the initial rule is kept "as is":

 {*,!}["People","Customer"].rd(name,departure) &
 {*,!}["People","Destination"].rd(name,arrival) &
 {*,!}["Metro","Connection"].rd(line,departure,arrival)
 ::
 {
 ["People","Customer"].get(name,departure) ;
 ["People","Destination"].get(name,arrival) ;
 ["Metro","Connection"].rd(line,departure,arrival) ;
 ["People","Customer"].put(name,arrival) ;
 ["Supervision","Travel"].put(line,departure,arrival,name)
 }.

A new "2-hop" rule is inserted.

This rule introduces a shared intermediate station, called via, between the first and second halves of the travel.

 {*,!}["People","Customer"].rd(name,departure) &
 {*,!}["People","Destination"].rd(name,arrival) &
 {*,!}["Metro","Connection"].rd(line1,departure,via) &   <---- here 'via' is an arrival station
 {*,!}["Metro","Connection"].rd(line2,via,arrival) &     <---- here 'via' is propagated as a departure station
 ::
 {
 ["People","Customer"].get(name,departure) ;
 ["People","Destination"].get(name,arrival) ;
 ["Metro","Connection"].rd(line1,departure,via) ; <---- here 'via' is an arrival station
 ["Metro","Connection"].rd(line2,via,arrival) ;   <---- and 'via' is a departure station. Thus we manage the change in metro.
 ["People","Customer"].put(name,arrival) ;
 ["Supervision","Travel"].put(line1,departure,via,name) ;
 ["Supervision","Travel"].put(line2,via,arrival,name) ;
 ["Supervision","Travel"].put("2-hop",departure,arrival,name)  <---- "2-hop" is inserted for traceability reasons
 }.

In the end, the trom.ls script contains 2 rules.

  • The first one manages "direct" travel,
  • while the second one manages journeys requiring a change of metro lines.

As the Destination of the Customer is updated while the production part of the rule is performed, only one or the other rule is triggered for a given configuration.

As previously done, start the application and run the scripts with following command :

python quinoa.py --go

Results

Initial state of the bags

| People.Customer| People.Destination| Metro.Connection| Supervision.Travel| |---|---|---|---| | ("Alice","A")| ("Alice","D")| ("red","A","B")|| | ("bob","B")| ("bob","D")| ("lightblue","A","D")|| | ("charles","C")| ("charles","D")| ("yellow","C","D")|| | ("denis","A")| ("denis","D")| ("red","B","A")|| ||| ("lightblue","D","A")|| ||| ("yellow","D","C")||

The state of bags after the rules are enacted:

| People.Customer| People.Destination| Metro.Connection| Supervision.Travel| |---|---|---|---| | ("alice","D")|| ("red","A","B")| ("lightblue","A","D","alice")| | ("bob","D")|| ("lightblue","A","D")| ("red","B","A","bob)| | ("charles","D")|| ("yellow","C","D")| ("lightblue","A","D","bob")| | ("denis","D")|| ("red","B","A")| ("2-hop","B","D","bob")| ||| ("lightblue","D","A")| ("yellow","C","D","charles")| ||| ("yellow","D","C")| ("lightblue","A","D","denis")|

We note that Bob used two lines (red (B,A) and lightblue(A,D)) to reach his destination. The line change is confirmed by the ("2-hop", "B", "D", "bob") traceability resource.