1 | package dk.deepthought.sidious.rules; |
2 | |
3 | import java.util.Collection; |
4 | |
5 | import dk.deepthought.sidious.goalhandler.Goal; |
6 | import dk.deepthought.sidious.greenhouse.ClimaticState; |
7 | import dk.deepthought.sidious.greenhouse.SensorInput; |
8 | import dk.deepthought.sidious.supportsystem.Adjustable; |
9 | import dk.deepthought.sidious.supportsystem.Repository; |
10 | import dk.deepthought.sidious.supportsystem.State; |
11 | import dk.deepthought.sidious.supportsystem.Step; |
12 | import dk.deepthought.sidious.supportsystem.SuperLinkID; |
13 | |
14 | /** |
15 | * This is the base class for representing a Rule. It is designed to be extended |
16 | * by classes defining rules of the system. |
17 | * <p> |
18 | * Rules can be goal-oriented and work towards a specific goal. They can also |
19 | * represent a conflict or an expense. |
20 | * |
21 | * @author Deepthought |
22 | * |
23 | */ |
24 | public abstract class Rule { |
25 | |
26 | /** |
27 | * The ID of the originating <code>PlanRequester</code>. |
28 | */ |
29 | private SuperLinkID parentID; |
30 | |
31 | /** |
32 | * Method returns a collection of immediate goals. |
33 | * <p> |
34 | * If there are no immediate goals, an empty collection is returned. |
35 | * |
36 | * @return the goals of this rule |
37 | */ |
38 | public abstract Collection<Goal> getGoals(); |
39 | |
40 | /** |
41 | * Method returns the calculated desire associated with the change from |
42 | * <code>currentState</code> to <code>newState</code>. |
43 | * <p> |
44 | * The calculated desire must evaluate to [0,1], where 0 represents no |
45 | * desire for changing state, and 1 represents maximum desire for change. |
46 | * <p> |
47 | * Some rules are allowed to evaluate to values (much) larger than 1. This |
48 | * exception is only allowed if the outcome of <b>not</b> respecting the |
49 | * rule is fatal. |
50 | * |
51 | * @param currentState |
52 | * the current state |
53 | * @param newState |
54 | * the new state |
55 | * @param step |
56 | * the step |
57 | * |
58 | * @return the calculated desire |
59 | */ |
60 | public abstract double desire(State currentState, State newState, Step step); |
61 | |
62 | /** |
63 | * Gets the explanation/reasoning from a rule. |
64 | * <p> |
65 | * Override this method if a more detailed explanation is needed. |
66 | * @return The explanation. |
67 | */ |
68 | public String getExplanation() { |
69 | return getClass().getSimpleName(); |
70 | } |
71 | |
72 | /** |
73 | * Gets the parent id of this rule. |
74 | * |
75 | * @return the parentID |
76 | */ |
77 | public SuperLinkID getParentID() { |
78 | return parentID; |
79 | } |
80 | |
81 | /** |
82 | * Sets the parent id for this rule. |
83 | * |
84 | * @param parentID |
85 | * the parentID to set |
86 | */ |
87 | public void setParentID(SuperLinkID parentID) { |
88 | this.parentID = parentID; |
89 | } |
90 | |
91 | /** |
92 | * Method returns the value of the input <code>sensorID</code> in the |
93 | * input <code>state</code>. If the sensor isn't represented in the |
94 | * state, 0 is returned. |
95 | * |
96 | * @param state |
97 | * the state |
98 | * @param sensorID |
99 | * 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 | } |