1 10 package com.hp.hpl.jena.reasoner.rulesys.impl; 11 12 import java.util.*; 13 14 import com.hp.hpl.jena.reasoner.TriplePattern; 15 16 30 public class Generator implements LPAgendaEntry, LPInterpreterContext { 31 32 34 protected LPInterpreter interpreter; 35 36 37 protected ArrayList results = new ArrayList(); 38 39 41 protected Set resultSet; 42 43 44 protected boolean isReady = true; 45 46 47 protected boolean checkReadyNeeded = false; 48 49 50 protected Set generatingCPs = new HashSet(); 51 52 53 protected Set consumingCPs = new HashSet(); 54 55 56 protected LFlag completionState; 57 58 59 protected TriplePattern goal; 60 61 62 protected boolean isSingleton; 63 64 70 76 public Generator(LPInterpreter interpreter, TriplePattern goal) { 77 this.interpreter = interpreter; 78 this.goal = goal; isSingleton = goal.isGround(); 80 if (!isSingleton) resultSet = new HashSet(); 81 } 82 83 86 public int numResults() { 87 return results.size(); 88 } 89 90 94 public boolean isReady() { 95 if (isComplete()) return false; 96 if (checkReadyNeeded) { 97 isReady = false; 98 for (Iterator i = generatingCPs.iterator(); i.hasNext(); ) { 99 if ( ((ConsumerChoicePointFrame)i.next()).isReady() ) { 100 isReady = true; 101 break; 102 } 103 } 104 checkReadyNeeded = false; 105 return isReady; 106 } else { 107 return isReady; 108 } 109 } 110 111 115 public void setReady(ConsumerChoicePointFrame ccp) { 116 if (!isComplete()) { 117 interpreter.engine.schedule(ccp); 118 isReady = true; 119 checkReadyNeeded = false; 120 } 121 } 122 123 126 public boolean isComplete() { 127 return interpreter == null; 128 } 129 130 137 145 148 public void setComplete() { 149 if (!isComplete()) { 150 interpreter.close(); 151 interpreter = null; 152 resultSet = null; 153 isReady = false; 154 completionState = LFlag.DEAD; 155 for (Iterator i = consumingCPs.iterator(); i.hasNext(); ) { 157 ConsumerChoicePointFrame ccp = (ConsumerChoicePointFrame)i.next(); 158 if ( ! ccp.isReady()) { 159 ccp.setFinished(); 160 } 161 } 162 generatingCPs = null; 163 consumingCPs.clear(); 164 } 165 } 166 167 170 public void addConsumer(ConsumerChoicePointFrame ccp) { 171 consumingCPs.add(ccp); 172 } 176 177 180 public void removeConsumer(ConsumerChoicePointFrame ccp) { 181 consumingCPs.remove(ccp); 182 } 190 191 194 public void notifyResults() { 195 LPBRuleEngine engine = interpreter.getEngine(); 196 for (Iterator i = consumingCPs.iterator(); i.hasNext(); ) { 197 ConsumerChoicePointFrame cons = (ConsumerChoicePointFrame)i.next(); 198 cons.setReady(); 199 } 200 } 201 202 205 public void notifyBlockedOn(ConsumerChoicePointFrame ccp) { 206 generatingCPs.add(ccp); 207 checkReadyNeeded = true; 208 } 209 210 214 public void notifyFinished(ConsumerChoicePointFrame ccp) { 215 if (generatingCPs != null) { 216 generatingCPs.remove(ccp); 217 } 218 checkReadyNeeded = true; 219 } 220 221 225 public void pump() { 226 pump(this); 227 } 228 229 234 public void pump(LPInterpreterState context) { 235 if (isComplete()) return; 236 interpreter.setState(context); 237 int priorNresults = results.size(); 238 while (true) { 239 Object result = interpreter.next(); 240 if (result == StateFlag.FAIL) { 241 checkReadyNeeded = true; 242 break; 243 } else { 244 if (isSingleton) { 246 results.add(result); 247 isReady = false; 248 break; 249 } else if (resultSet.add(result)) { 250 results.add(result); 251 } 252 } 253 } 254 if (results.size() > priorNresults) { 255 notifyResults(); 256 } 257 if (isSingleton && results.size() == 1) { 259 setComplete(); 260 } 261 if (LPBRuleEngine.CYCLES_BETWEEN_COMPLETION_CHECK == 0) { 262 checkForCompletions(); 263 } 264 } 265 266 269 public Generator getGenerator() { 270 return this; 271 } 272 273 277 public void checkForCompletions() { 278 HashSet visited = new HashSet(); 279 if (runCompletionCheck(visited) != LFlag.LIVE) { 280 postCompletionCheckScan(visited); 281 } 282 } 283 284 288 public static void checkForCompletions(Collection completions) { 289 HashSet visited = new HashSet(); 290 boolean atLeastOneZombie = false; 291 for (Iterator i = completions.iterator(); i.hasNext(); ) { 292 Generator g = (Generator)i.next(); 293 if (g.runCompletionCheck(visited) != LFlag.LIVE) { 294 atLeastOneZombie = true; 295 } 296 } 297 if (atLeastOneZombie) { 298 postCompletionCheckScan(visited); 299 } 300 } 301 302 307 protected LFlag runCompletionCheck(Set visited) { 308 if (isComplete()) return LFlag.DEAD; 309 if (! visited.add(this)) return this.completionState; 310 completionState = LFlag.UNKNOWN; 311 if (isReady()) { 312 completionState = LFlag.LIVE; 313 } else { 314 for (Iterator i = generatingCPs.iterator(); i.hasNext(); ) { 315 ConsumerChoicePointFrame ccp = (ConsumerChoicePointFrame)i.next(); 316 if (ccp.isReady()) { 317 completionState = LFlag.LIVE; 318 break; 319 } else if ( ccp.generator.runCompletionCheck(visited) == LFlag.LIVE) { 320 completionState = LFlag.LIVE; 321 break; 322 } 323 } 324 } 325 return completionState; 326 } 327 328 333 protected static void postCompletionCheckScan(Set visited ) { 334 for (Iterator iv = visited.iterator(); iv.hasNext(); ) { 335 Generator g = (Generator)iv.next(); 336 if (g.completionState == LFlag.LIVE) { 337 for (Iterator i = g.consumingCPs.iterator(); i.hasNext(); ) { 338 LPInterpreterContext link = ((ConsumerChoicePointFrame)i.next()).getConsumingContext(); 339 if (link instanceof Generator) { 340 ((Generator)link).propagateLive(visited); 341 } 342 } 343 } 344 } 345 346 for (Iterator iv = visited.iterator(); iv.hasNext(); ) { 347 Generator g = (Generator)iv.next(); 348 if (g.completionState != LFlag.LIVE) { 349 g.setComplete(); 350 } 351 } 352 return; 353 } 354 355 359 protected void propagateLive(Set filter) { 360 if (completionState != LFlag.LIVE) { 361 completionState = LFlag.LIVE; 362 for (Iterator i = consumingCPs.iterator(); i.hasNext(); ) { 363 LPInterpreterContext link = ((ConsumerChoicePointFrame)i.next()).getConsumingContext(); 364 if (link instanceof Generator) { 365 ((Generator)link).propagateLive(filter); 366 } 367 } 368 } 369 } 370 371 374 private static class LFlag { 375 376 377 private String label; 378 379 public static final LFlag LIVE = new LFlag("Live"); 380 public static final LFlag DEAD = new LFlag("Dead"); 381 public static final LFlag UNKNOWN = new LFlag("Unknown"); 382 383 384 private LFlag(String label) { 385 this.label = label; 386 } 387 388 389 public String toString() { 390 return label; 391 } 392 } 393 394 395 } 396 397 398 | Popular Tags |