001 package dk.deepthought.sidious.rules;
002
003 import java.util.Collection;
004
005 import dk.deepthought.sidious.goalhandler.Goal;
006 import dk.deepthought.sidious.greenhouse.ClimaticState;
007 import dk.deepthought.sidious.greenhouse.SensorInput;
008 import dk.deepthought.sidious.supportsystem.Adjustable;
009 import dk.deepthought.sidious.supportsystem.Repository;
010 import dk.deepthought.sidious.supportsystem.State;
011 import dk.deepthought.sidious.supportsystem.Step;
012 import dk.deepthought.sidious.supportsystem.SuperLinkID;
013
014 /**
015 * This is the base class for representing a Rule. It is designed to be extended
016 * by classes defining rules of the system.
017 * <p>
018 * Rules can be goal-oriented and work towards a specific goal. They can also
019 * represent a conflict or an expense.
020 *
021 * @author Deepthought
022 *
023 */
024 public abstract class Rule {
025
026 /**
027 * The ID of the originating <code>PlanRequester</code>.
028 */
029 private SuperLinkID parentID;
030
031 /**
032 * Method returns a collection of immediate goals.
033 * <p>
034 * If there are no immediate goals, an empty collection is returned.
035 *
036 * @return the goals of this rule
037 */
038 public abstract Collection<Goal> getGoals();
039
040 /**
041 * Method returns the calculated desire associated with the change from
042 * <code>currentState</code> to <code>newState</code>.
043 * <p>
044 * The calculated desire must evaluate to [0,1], where 0 represents no
045 * desire for changing state, and 1 represents maximum desire for change.
046 * <p>
047 * Some rules are allowed to evaluate to values (much) larger than 1. This
048 * exception is only allowed if the outcome of <b>not</b> respecting the
049 * rule is fatal.
050 *
051 * @param currentState
052 * the current state
053 * @param newState
054 * the new state
055 * @param step
056 * the step
057 *
058 * @return the calculated desire
059 */
060 public abstract double desire(State currentState, State newState, Step step);
061
062 /**
063 * Gets the explanation/reasoning from a rule.
064 * <p>
065 * Override this method if a more detailed explanation is needed.
066 * @return The explanation.
067 */
068 public String getExplanation() {
069 return getClass().getSimpleName();
070 }
071
072 /**
073 * Gets the parent id of this rule.
074 *
075 * @return the parentID
076 */
077 public SuperLinkID getParentID() {
078 return parentID;
079 }
080
081 /**
082 * Sets the parent id for this rule.
083 *
084 * @param parentID
085 * the parentID to set
086 */
087 public void setParentID(SuperLinkID parentID) {
088 this.parentID = parentID;
089 }
090
091 /**
092 * Method returns the value of the input <code>sensorID</code> in the
093 * input <code>state</code>. If the sensor isn't represented in the
094 * state, 0 is returned.
095 *
096 * @param state
097 * the state
098 * @param sensorID
099 * the id
100 * @return the value of the sensor
101 */
102 protected double getSensorValue(State state, SuperLinkID sensorID) {
103 if (state instanceof ClimaticState) {
104 ClimaticState currentClima = (ClimaticState) state;
105 for (SensorInput input : currentClima.getSensors()) {
106 if (input.getID().equals(sensorID)) {
107 return input.getValue();
108 }
109 }
110 }
111 return 0;
112 }
113
114 /**
115 * Method returns the setting of the input adjustable.
116 *
117 * @param adjustableID
118 * id of the adjustable
119 * @return the setting
120 */
121 protected double getAdjustableSettingFromParent(SuperLinkID adjustableID) {
122 //FIXME WHY is this method not static?
123 //Check use and visibility
124 return Repository.getBlackboard().getAdjustableSetting(parentID,
125 adjustableID);
126 }
127
128 /**
129 * Returns the setting of an adjustable contained in the <code>step</code>
130 * identified by the <code>id</code>.
131 *
132 * @param step
133 * the step
134 * @param id
135 * the id
136 * @return the setting
137 */
138 protected double getAdjustableSetting(Step step, SuperLinkID id) {
139 //FIXME WHY is this method not static?
140 //Check use and visibility
141 if (step == null) {
142 return 0;
143 }
144 Collection<Adjustable> adjustables = step.getAdjustables();
145 for (Adjustable adjustable : adjustables) {
146 if (adjustable.getID().equals(id)) {
147 return adjustable.getSetting();
148 }
149 }
150 return 0;
151 }
152
153 }
|