public void build(BuildContext context, BuildUtils utils, RuleConditionElement rce) {
    NamedConsequence namedConsequence = (NamedConsequence) rce;

    Timer timer = context.getRule().getTimer();
    if (timer != null) {
      ReteooComponentBuilder builder = utils.getBuilderFor(Timer.class);
      builder.build(context, utils, context.getRule().getTimer());
    }

    RuleTerminalNode terminalNode = buildTerminalNodeForNamedConsequence(context, namedConsequence);

    terminalNode.attach(context);

    terminalNode.networkUpdated(new UpdateContext());

    // adds the terminal node to the list of nodes created/added by this sub-rule
    context.getNodes().add(terminalNode);

    if (timer != null) {
      context.setTupleSource(context.getTupleSource().getLeftTupleSource());
    }

    context.setTerminated(namedConsequence.isTerminal());
  }
Beispiel #2
0
  /**
   * This returns true is the rule is effective. If the rule is not effective, it cannot activate.
   *
   * <p>This uses the dateEffective, dateExpires and enabled flag to decide this.
   */
  public boolean isEffective(Tuple tuple, RuleTerminalNode rtn, WorkingMemory workingMemory) {
    if (!this.enabled.getValue(tuple, rtn.getEnabledDeclarations(), this, workingMemory)) {
      return false;
    }
    if (this.dateEffective == null && this.dateExpires == null) {
      return true;
    } else {
      Calendar now = Calendar.getInstance();
      now.setTimeInMillis(workingMemory.getSessionClock().getCurrentTime());

      if (this.dateEffective != null && this.dateExpires != null) {
        return (now.after(this.dateEffective) && now.before(this.dateExpires));
      } else if (this.dateEffective != null) {
        return (now.after(this.dateEffective));
      } else {
        return (now.before(this.dateExpires));
      }
    }
  }
  private int fire(
      InternalWorkingMemory wm,
      AgendaFilter filter,
      int fireCount,
      int fireLimit,
      LinkedList<StackEntry> outerStack,
      InternalAgenda agenda,
      boolean fireUntilHalt) {
    int localFireCount = 0;
    if (!tupleList.isEmpty()) {
      RuleTerminalNode rtn = (RuleTerminalNode) pmem.getNetworkNode();

      if (!fireExitedEarly && isDeclarativeAgendaEnabled()) {
        // Network Evaluation can notify meta rules, which should be given a chance to fire first
        RuleAgendaItem nextRule = agenda.peekNextRule();
        if (!isHighestSalience(nextRule, ruleAgendaItem.getSalience())) {
          fireExitedEarly = true;
          return localFireCount;
        }
      }

      while (!tupleList.isEmpty()) {
        LeftTuple leftTuple;
        if (queue != null) {
          leftTuple = (LeftTuple) queue.dequeue();
          tupleList.remove(leftTuple);
        } else {
          leftTuple = tupleList.removeFirst();
          ((Activation) leftTuple).setQueued(false);
        }

        rtn =
            (RuleTerminalNode)
                leftTuple
                    .getSink(); // branches result in multiple RTN's for a given rule, so unwrap per
        // LeftTuple
        RuleImpl rule = rtn.getRule();

        PropagationContext pctx = leftTuple.getPropagationContext();
        pctx = RuleTerminalNode.findMostRecentPropagationContext(leftTuple, pctx);

        // check if the rule is not effective or
        // if the current Rule is no-loop and the origin rule is the same then return
        if (cancelAndContinue(wm, rtn, rule, leftTuple, pctx, filter)) {
          continue;
        }

        AgendaItem item = (AgendaItem) leftTuple;
        if (agenda.getActivationsFilter() != null
            && !agenda.getActivationsFilter().accept(item, wm, rtn)) {
          // only relevant for seralization, to not refire Matches already fired
          continue;
        }

        agenda.fireActivation(item);
        localFireCount++;

        if (rtn.getLeftTupleSource() == null) {
          break; // The activation firing removed this rule from the rule base
        }

        int salience =
            ruleAgendaItem.getSalience(); // dyanmic salience may have updated it, so get again.
        if (queue != null && !queue.isEmpty() && salience != queue.peek().getSalience()) {
          ruleAgendaItem.dequeue();
          ruleAgendaItem.setSalience(queue.peek().getSalience());
          ruleAgendaItem.getAgendaGroup().add(ruleAgendaItem);
          salience = ruleAgendaItem.getSalience();
        }

        RuleAgendaItem nextRule = agenda.peekNextRule();
        if (haltRuleFiring(nextRule, fireCount, fireLimit, localFireCount, agenda, salience)) {
          break; // another rule has high priority and is on the agenda, so evaluate it first
        }
        reEvaluateNetwork(wm, outerStack, fireUntilHalt);
        wm.executeQueuedActions();

        if (tupleList.isEmpty() && !outerStack.isEmpty()) {
          // the outer stack is nodes needing evaluation, once all rule firing is done
          // such as window expiration, which must be done serially
          StackEntry entry = outerStack.removeFirst();
          NETWORK_EVALUATOR.evalStackEntry(entry, outerStack, outerStack, this, wm);
        }
      }
    }

    removeRuleAgendaItemWhenEmpty(wm);

    fireExitedEarly = false;
    return localFireCount;
  }
Beispiel #4
0
 public boolean isEnabled(Tuple tuple, RuleTerminalNode rtn, WorkingMemory workingMemory) {
   return this.enabled.getValue(tuple, rtn.getEnabledDeclarations(), this, workingMemory);
 }