/** * */ package eu.quanticol.carma.simulator; import java.util.HashMap; import java.util.LinkedList; import java.util.Map; import org.apache.commons.math3.random.RandomGenerator; import org.cmg.ml.sam.sim.Activity; import org.cmg.ml.sam.sim.ModelI; import org.cmg.ml.sam.sim.sampling.Measure; import org.cmg.ml.sam.sim.util.ComposedWeightedStructure; import org.cmg.ml.sam.sim.util.WeightedStructure; import eu.quanticol.carma.simulator.space.SpaceModel; /** * @author loreti * */ public abstract class CarmaSystem implements ModelI { private static SpaceModel currentSpaceModel = new SpaceModel(); public static void setCurrentSpaceModel( SpaceModel model ) { if (model != null) { currentSpaceModel = model; } else { currentSpaceModel = new SpaceModel(); } } public static SpaceModel getCurrentSpaceModel() { return currentSpaceModel; } public static final String LOC_ATTRIBUTE_NAME = "loc"; protected LinkedList<CarmaComponent> collective; protected CarmaStore global; protected double now; protected final SpaceModel space; public CarmaSystem( ) { this( new SpaceModel() ); } public CarmaSystem( SpaceModel space ) { setCurrentSpaceModel(space); this.global = new CarmaStore(); this.collective = new LinkedList<CarmaComponent>(); this.now = 0.0; this.space = space; } public SpaceModel getSpaceModel() { return this.space; } public void broadcastOutput( RandomGenerator r , CarmaComponent sender, int action, CarmaPredicate predicate, Object value) { for (CarmaComponent c : collective) { if (c!=sender) { c.inputBroadcast(r , this , sender , action , predicate , value ); } } } public void removeKilled() { LinkedList<CarmaComponent> newCollective = new LinkedList<>(); for (CarmaComponent carmaComponent : collective) { if (!carmaComponent.isKilled()) { newCollective.add(carmaComponent); } } this.collective = newCollective; } public void setGLobalAttribute( String attribute , Object value ) { global.set(attribute, value); } public <T> T getGlobalAttribute( String attribute, Class<T> clazz ) { return global.get(attribute, clazz); } public boolean unicastOutput( RandomGenerator r , CarmaComponent sender, int action, CarmaPredicate predicate, Object value) { WeightedStructure<Activity> activeInputs = new ComposedWeightedStructure<Activity>(); for (CarmaComponent caspaComponent : collective) { if (sender != caspaComponent) { activeInputs = activeInputs.add( caspaComponent.inputUnicast(this,sender,action,predicate,value) ); } } if (activeInputs.getTotalWeight()>0.0) { double foo = r.nextDouble(); foo = foo*activeInputs.getTotalWeight(); activeInputs.select(foo).getElement().execute(r); return true; } return false; } public abstract double broadcastProbability( CarmaStore sender , CarmaStore receiver , int action ); public abstract double unicastProbability( CarmaStore sender , CarmaStore receiver , int action ); public abstract double broadcastRate( CarmaStore sender , int action ); public abstract double unicastRate( CarmaStore sender , int action ); public abstract void broadcastUpdate( RandomGenerator random , CarmaStore sender , int action , Object value ); public abstract void unicastUpdate( RandomGenerator random , CarmaStore sender , CarmaStore receiver, int action , Object value ); public int count( CarmaPredicate p ) { int counter = 0; for (CarmaComponent caspaComponent : collective) { try { if (p.satisfy(now,caspaComponent.store)) { counter++; } } catch (NullPointerException e) { } } return counter; } public void addComponent( CarmaComponent c ) { this.collective.add(c); } public LinkedList<CarmaComponent> getCollective() { return collective; } /* (non-Javadoc) * @see org.cmg.ml.sam.sim.ModelI#getActions() */ @Override public WeightedStructure<Activity> getActivities( RandomGenerator r ) { WeightedStructure<Activity> toReturn = new ComposedWeightedStructure<Activity>(); for (CarmaComponent caspaComponent : collective) { toReturn = toReturn.add( caspaComponent.getActivities( this ) ); } return toReturn; } /* (non-Javadoc) * @see org.cmg.ml.sam.sim.ModelI#timeStep(double) */ @Override public void timeStep(double dt) { this.now += dt; } public double now() { return now; } public int measure( ComponentPredicate p ) { int count = 0; for (CarmaComponent c : collective) { try { if (p.eval(now,c)) { count++; } } catch (NullPointerException e) { } } return count; } public double min( Measure<CarmaStore> m , CarmaPredicate guard ) { double value = Double.POSITIVE_INFINITY; for (CarmaComponent carmaComponent : collective) { try { if (guard.satisfy(now,carmaComponent.store)) { double v = m.measure(carmaComponent.store); if (v<value) { value = v; } } } catch (NullPointerException e) { } } return value; } public double max( Measure<CarmaStore> m , CarmaPredicate guard ) { double value = Double.NEGATIVE_INFINITY; for (CarmaComponent carmaComponent : collective) { try { if (guard.satisfy(now,carmaComponent.store)) { double v = m.measure(carmaComponent.store); if (v>value) { value = v; } } } catch (NullPointerException e ){ } } return value; } public double average( Measure<CarmaStore> m , CarmaPredicate guard ) { double value = 0.0; int count = 0; for (CarmaComponent carmaComponent : collective) { try { if (guard.satisfy(now,carmaComponent.store)) { value += m.measure(carmaComponent.store); count++; } } catch (NullPointerException e) { } } return value/count; } /* (non-Javadoc) * @see java.lang.Object#toString() */ @Override public String toString() { return global.toString()+"|-"+this.collective.toString(); } public Iterable<CarmaComponent> components() { return collective; } public CarmaStore getGlobalStore() { return global; } public static <T> T uniform( RandomGenerator rg , T ... args ) { int idx = rg.nextInt(args.length); return args[idx]; } public LinkedList<Map<String,Object>> retrieve( CarmaPredicate guard , String[] attributes ) { LinkedList<Map<String,Object>> toReturn = new LinkedList<>(); for (CarmaComponent carmaComponent : collective) { if (guard.satisfy(now,carmaComponent.store)) { HashMap<String,Object> data = new HashMap<>(); for( int i=0 ; i<attributes.length ; i++ ) { Object foo = carmaComponent.get(attributes[i], Object.class ); if (foo != null) { data.put( attributes[i] , foo ); } } toReturn.add(data); } } return toReturn; } }