/** * @param Rule[] $expectedRules * @param WorkingMemory $workingMemory */ protected function assertExplanation($expectedRules, WorkingMemory $workingMemory) { $executed = $workingMemory->getExecutedRules(); $this->assertEquals(sizeof($expectedRules), sizeof($executed)); foreach ($expectedRules as $i => $expectedRule) { $this->assertTrue(isset($executed[$i])); $this->assertEquals($expectedRule, $executed[$i]); } }
/** * @param Rule $rule * @param WorkingMemory $workingMemory * * @return array */ public function execute(Rule $rule, WorkingMemory $workingMemory) { $facts = $workingMemory->getAllFacts(); /** * @param string $_action * @return array */ $executor = function ($_action) use($facts) { extract($facts); unset($facts); eval($_action); unset($_action); return get_defined_vars(); }; $workingMemory->setAllFacts($executor($rule->getAction())); $workingMemory->setExecuted($rule->getRule()); }
/** * Calculate possible wildcards */ protected function calculateWildcardCombinations() { $wildCards = $this->getConditionWildcards(); if (sizeof($wildCards) > 2) { throw new \Exception('More than 2 wildcards is not yet supported'); } $combinations = $this->combinations($this->workingMemory->getAllFacts(), sizeof($wildCards)); foreach ($combinations as $i => $combination) { $proccesedCondition = $this->parseCode($this->getCondition(), $this->getConditionWildcards(), $combination); $proccesedAction = $this->parseCode($this->getAction(), $this->getConditionWildcards(), $combination); $rule = Rule::factory($this->getName() . '__' . $i, $proccesedCondition, $proccesedAction, $this->getPriority()); $this->wildcardCombinationRules[] = $rule; } }
/** * @param KnowledgeBase $knowledgeBase * * @return WorkingMemory */ public function run(KnowledgeBase $knowledgeBase) { $workingMemory = new WorkingMemory(); $workingMemory->setFacts($knowledgeBase->getFacts()); $this->inferenceProfiler && $this->inferenceProfiler->startInference($knowledgeBase->getFacts()); while ($matchedRules = $this->getMatchedRules($knowledgeBase, $workingMemory)) { /** @var RuleRunDecorator $selectedRuleDecorator */ $selectedRuleDecorator = $this->conflictResolutionStrategy->selectPreferredRule($matchedRules, $workingMemory); $this->ruleExecutor->execute($selectedRuleDecorator, $workingMemory); } $this->inferenceProfiler && $this->inferenceProfiler->endInference($knowledgeBase->getFacts()); $knowledgeBase->setFacts($workingMemory->getAllFacts()); return $workingMemory; }
/** * @param Rule $rule * @param WorkingMemory $workingMemory * * @return array */ public function execute(Rule $rule, WorkingMemory $workingMemory) { if ($rule instanceof RuleRunDecorator && $rule->hasSuccessCombinationRules()) { $workingMemory->setExecuted($rule->getRule()); foreach ($rule->getSuccessCombinationRules() as $combinationRule) { $this->inferenceProfiler && $this->inferenceProfiler->addIterationRuleExecution($combinationRule); $workingMemory->setAllFacts($this->execAction($combinationRule, $workingMemory)); $workingMemory->setExecuted($combinationRule); } } else { $this->inferenceProfiler && $this->inferenceProfiler->addIterationRuleExecution($rule); $workingMemory->setAllFacts($this->execAction($rule, $workingMemory)); $workingMemory->setExecuted($rule->getRule()); } }