My input is Position report of a vehicle:
0,0,107,32,0,0,0,10,53320,-1,-1,-1,-1,-1,-1
0,0,107,32,0,0,0,10,53320,-1,-1,-1,-1,-1,-1
0,0,107,32,0,0,0,10,53320,-1,-1,-1,-1,-1,-1
0,0,107,32,0,0,0,10,53320,-1,-1,-1,-1,-1,-1
0,0,109,20,0,0,0,19,53320,-1,-1,-1,-1,-1,-1
0,0,109,20,0,0,0,19,53320,-1,-1,-1,-1,-1,-1
0,0,106,28,0,0,0,26,137745,-1,-1,-1,-1,-1,-1
0,0,109,20,0,0,0,19,53320,-1,-1,-1,-1,-1,-1
0,0,109,20,0,0,0,19,53320,-1,-1,-1,-1,-1,-1
In order, these are: Type, Time, VID, Spd, XWay, Lane, Dir, Seg, Pos, QID, Sinit, Send, DOW, TOD and Day.
Problem statement:
Alert Accident if two or more vehicles have more than three position report as same.
The rule works well with the DRL attached below.
To make it work I've included 'retract (vehLoc);' in the rule "Identify Collided Vehicles". Which I don't want to do. If I comment this line, rules are getting fired again with first record of VID '107'.
Though I include no-loop true, still the rules are fired when i modify either Vehicle location or Statistics.
May I know what else I can do to achieve desired functionality?
Output: (with retract (vehLoc);)
Setup statistics
Add to stopped cars -- 107---2
Identify Collided Vehicles---2----107
Add to stopped cars -- 107---3
Identify Collided Vehicles---3----107
Add to stopped cars -- 107---4
Identify Collided Vehicles---4----107
Add to stopped cars -- 109---5
Identify Collided Vehicles---5----109
Add to stopped cars -- 109---6
Identify Collided Vehicles---6----109
Add to stopped cars -- 106---7
Identify Collided Vehicles---1----106
Add to stopped cars -- 109---8
Identify Collided Vehicles---7----109
Add to stopped cars -- 109---9
Identify Collided Vehicles---8----109
no of veh : 2
Detect Accident
no of veh : 2
Output: (without retract (vehLoc);)
Setup statistics
Add to stopped cars -- 107---2
Identify Collided Vehicles---2----107
Add to stopped cars -- 107---3
Identify Collided Vehicles---3----107
Add to stopped cars -- 107---4
Identify Collided Vehicles---4----107
Add to stopped cars -- 107---5
Identify Collided Vehicles---5----107
Add to stopped cars -- 107---6
Identify Collided Vehicles---6----107
Add to stopped cars -- 107---7
Identify Collided Vehicles---7----107
Add to stopped cars -- 107---8
Identify Collided Vehicles---8----107
Add to stopped cars -- 107---9
Identify Collided Vehicles---9----107
Add to stopped cars -- 107---10
Identify Collided Vehicles---10----107
Add to stopped cars -- 107---11
Identify Collided Vehicles---11----107
Here is my DRL
package com.hp.hpl.CHAOS.LR;
# importing classes
import java.lang.Integer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import com.hp.hpl.CHAOS.Rules.VehicleLocation;
global java.lang.String output
declare VehicleLocation
@role ( event )
@expires ( 1m )
end
declare Statistics
smashedcars : ArrayList
stopped_cars : ArrayList
accidents : ArrayList
collided_at : HashMap
end
rule "Setup statistics"
salience 110
no-loop true
when
not( Statistics( ) )
vehLoc : VehicleLocation()
then
Statistics s = new Statistics();
s.setSmashedcars (new ArrayList());
s.setStopped_cars (new ArrayList());
s.getStopped_cars().add(vehLoc);
s.setCollided_at(new HashMap());
insert( s );
System.out.println("Setup statistics");
end
rule "Add to stopped cars"
salience 100
no-loop true
when
vehLoc : VehicleLocation()
$stat : Statistics ()
((not( VehicleLocation(vid == vehLoc.vid) from $stat.getSmashedcars())))
then
modify($stat) {
getStopped_cars().add(vehLoc);
}
System.out.println("Add to stopped cars -- " + vehLoc.getVid() + "---" + $stat.getStopped_cars().size());
end
rule "Identify Collided Vehicles"
salience 90
no-loop true
when
vehLoc : VehicleLocation()
$stat : Statistics ()
$allStoppedcars : ArrayList( size > 0 )
from collect ( VehicleLocation(xway == vehLoc.xway,
pos == vehLoc.pos,
dir == vehLoc.dir,
lane == vehLoc.lane) from $stat.stopped_cars)
then
System.out.println("Identify Collided Vehicles" + "---" + $allStoppedcars.size() + "----" + vehLoc.getVid());
modify($stat) {
setCollided_at(collided_at($allStoppedcars,
vehLoc.getXway(),
vehLoc.getPos(),
vehLoc.getDir(),
vehLoc.getLane()));
}
retract (vehLoc);
end
rule "Detect Accident"
salience 80
no-loop true
when
$stat : Statistics (eval(collision_occured($stat.getCollided_at())))
then
System.out.println("Detect Accident");
end
function HashMap collided_at(ArrayList stopped_cars, int x, int pos, int dir, int lane) {
HashMap collided_at = new HashMap();
for (Iterator iterator = stopped_cars.iterator(); iterator.hasNext(); ) {
VehicleLocation vehLoc = (VehicleLocation) iterator.next();
if (vehLoc.getXway() == x
&& vehLoc.getPos() == pos
&& vehLoc.getDir() == dir
&& vehLoc.getLane() == lane) {
int key = vehLoc.getVid();
if (!collided_at.containsKey(key)) {
collided_at.put (key, new Integer(1));
continue;
}
collided_at.put (key, ((Integer)collided_at.get(key)).intValue()+1);
}
}
return collided_at;
}
function boolean collision_occured(HashMap collided_vehicles) {
java.util.Set entries = collided_vehicles.entrySet();
int noOfCollidedVehicles = 0;
java.util.Iterator iterator = entries.iterator();
while ( iterator.hasNext() ) {
java.util.Map.Entry object = (java.util.Map.Entry) iterator.next();
if ((Integer)object.getValue() > 3) {
noOfCollidedVehicles += 1;
}
}
if (noOfCollidedVehicles > 1) {
System.out.println("no of veh : " + noOfCollidedVehicles);
return true;
}
return false;
}