/**
  * Akce vracející pravidla pro vykreslení v easymineru
  * @param int $id
  * @param int $miner
  * @param string $task
  * @param string $rule
  * @throws BadRequestException
  * @throws ForbiddenRequestException
  */
 public function renderRuleDetails($id = null, $miner, $rule)
 {
     $rule = $this->rulesFacade->findRule($rule);
     //kontrola přístupů
     $task = $rule->task;
     $minerId = $miner;
     $miner = $task->miner;
     if ($miner->minerId != $minerId || $task->taskId != $id) {
         throw new ForbiddenRequestException($this->translator->translate('You are not authorized to access selected data!'));
     }
     $this->checkMinerAccess($miner);
     $this->template->rule = $rule;
 }
 /**
  * Akce pro odebrání celého obsahu rule clipboard z konkrétního rulesetu
  * @param int $id
  * @param int $miner
  * @param int $ruleset
  * @param string $returnRules ='' - IDčka oddělená čárkami, případně jedno ID
  * @throws ForbiddenRequestException
  * @throws BadRequestException
  */
 public function actionRemoveRulesFromRuleSet($id = null, $miner, $ruleset, $returnRules = '')
 {
     //načtení dané úlohy a zkontrolování přístupu k mineru
     $task = $this->tasksFacade->findTask($id);
     $this->checkMinerAccess($task->miner);
     $ruleIdsArr = explode(',', str_replace(';', ',', $returnRules));
     //najití RuleSetu a kontroly
     $ruleSet = $this->ruleSetsFacade->findRuleSet($ruleset);
     $this->ruleSetsFacade->checkRuleSetAccess($ruleSet, $this->user->id);
     //přidání pravidel
     $this->ruleSetsFacade->removeAllRuleClipboardRulesFromRuleSet($task, $ruleSet);
     $result = array();
     if (count($ruleIdsArr) > 0) {
         foreach ($ruleIdsArr as $ruleId) {
             try {
                 $rule = $this->rulesFacade->findRule($ruleId);
                 //TODO optimalizovat kontroly...
                 $ruleTask = $rule->task;
                 if ($ruleTask->taskId != $task->taskId) {
                     throw new InvalidArgumentException();
                 }
                 if ($ruleTask->miner->minerId != $miner) {
                     throw new InvalidArgumentException();
                 }
                 $result[$rule->ruleId] = $rule->getBasicDataArr();
             } catch (\Exception $e) {
                 continue;
             }
         }
     }
     $this->sendJsonResponse(array('rules' => $result));
 }
 /**
  * Funkce připravující pole s informacemi o vybraných pravidlech pro vrácení v rámci JSON odpovědi
  * @param int[] $ruleIdsArr
  * @param RuleSet|int $ruleSet
  * @return array
  */
 private function prepareRulesResult($ruleIdsArr, $ruleSet = null)
 {
     $result = [];
     if (!empty($ruleIdsArr)) {
         foreach ($ruleIdsArr as $ruleId) {
             if (!$ruleId) {
                 continue;
             }
             try {
                 $rule = $this->rulesFacade->findRule($ruleId);
                 $result[$rule->ruleId] = $rule->getBasicDataArr();
                 if (!empty($ruleSet)) {
                     $relation = $rule->getRuleSetRelation($ruleSet);
                     if (!empty($relation)) {
                         $result[$rule->ruleId]['ruleSetRelation'] = $relation->relation;
                     } else {
                         $result[$rule->ruleId]['ruleSetRelation'] = '';
                     }
                 }
             } catch (\Exception $e) {
                 continue;
             }
         }
     }
     return $result;
 }
 /**
  * Funkce pro kontrolu, jestli je zvolená úloha obsažená v Rule Clipboard
  * @param Task $task
  */
 public function checkTaskInRuleClipoard(Task &$task)
 {
     $rulesCount = $this->rulesFacade->getRulesCountByTask($task, true);
     if ($rulesCount != $task->rulesInRuleClipboardCount) {
         $task->rulesInRuleClipboardCount = $rulesCount;
         $this->saveTask($task);
     }
 }
 /**
  * Funkce pro nalezení pravidla dle zadaného ID a kontrolu oprávnění aktuálního uživatele pracovat s daným pravidlem
  * @param int $ruleId
  * @return RuleSet
  * @throws \Nette\Application\BadRequestException
  */
 private function findRuleWithCheckAccess($ruleId)
 {
     try {
         /** @var Rule $rule */
         $rule = $this->rulesFacade->findRule($ruleId);
     } catch (EntityNotFoundException $e) {
         $this->error('Requested rule was not found.');
         return null;
     }
     //TODO kontrola oprávnění
     return $rule;
 }
 /**
  * Funkce pro odebrání všech pravidel z RuleClipboard konkrétní úlohy z RuleSetu
  * @param $task
  * @param $ruleSet
  */
 public function removeAllRuleClipboardRulesFromRuleSet($task, $ruleSet)
 {
     if (!$ruleSet instanceof RuleSet) {
         $ruleSet = $this->findRuleSet($ruleSet);
     }
     $rules = $this->rulesFacade->findRulesByTask($task, null, null, null, true);
     if (!empty($rules)) {
         foreach ($rules as $rule) {
             $this->removeRuleFromRuleSet($rule, $ruleSet);
         }
     }
     $this->updateRuleSetRulesCount($ruleSet);
 }
 /**
  * Akce vracející pravidla pro vykreslení v easymineru
  * @param int $id
  * @param $offset
  * @param $limit
  * @param $order
  * @throws BadRequestException
  * @throws ForbiddenRequestException
  */
 public function actionGetRules($id, $offset = 0, $limit = 25, $order = 'rule_id')
 {
     if ($order == '') {
         $order = 'rule_id';
     }
     //nalezení daného mineru a kontrola oprávnění uživatele pro přístup k němu
     $task = $this->tasksFacade->findTask($id);
     $miner = $task->miner;
     $this->checkMinerAccess($miner);
     $rules = $this->rulesFacade->findRulesByTask($task, $order, $offset, $limit);
     $rulesArr = array();
     if (!empty($rules)) {
         foreach ($rules as $rule) {
             $rulesArr[$rule->ruleId] = $rule->getBasicDataArr();
         }
     }
     $this->sendJsonResponse(array('task' => array('name' => $task->name, 'rulesCount' => $task->rulesCount, 'IMs' => $task->getInterestMeasures(), 'state' => $task->state, 'importState' => $task->importState), 'rules' => $rulesArr));
 }
 /**
  * Akce pro odebrání pravidel z rulesetu
  * @param int $id
  * @param int|string $rules
  * @throws \Nette\Application\BadRequestException
  * @SWG\Delete(
  *   tags={"RuleSets"},
  *   path="/rule-sets/{id}/rules",
  *   summary="Remove rules from the selected rule set",
  *   security={{"apiKey":{}},{"apiKeyHeader":{}}},
  *   produces={"application/json","application/xml"},
  *   @SWG\Parameter(
  *     name="id",
  *     description="RuleSet ID",
  *     required=true,
  *     type="integer",
  *     in="path"
  *   ),
  *   @SWG\Parameter(
  *     name="rules",
  *     description="IDs of rules (optinally multiple - separated with , or ;)",
  *     required=true,
  *     type="array",
  *     @SWG\items(
  *       type="integer"
  *     ),
  *     collectionFormat="csv",
  *     in="query"
  *   ),
  *   @SWG\Response(
  *     response=200,
  *     description="Rules have been removed from the rule set.",
  *     @SWG\Schema(ref="#/definitions/StatusResponse"),examples={"code":200,"status":"OK"}
  *   ),
  *   @SWG\Response(response=404, description="Requested rule set was not found.")
  * )
  */
 public function actionDeleteRules($id, $rules)
 {
     /** @var RuleSet $ruleSet */
     $ruleSet = $this->findRuleSetWithCheckAccess($id);
     /** @var int[] $ruleIdsArr */
     $ruleIdsArr = explode(',', str_replace(';', ',', $rules));
     if (!empty($ruleIdsArr)) {
         foreach ($ruleIdsArr as $ruleId) {
             if (!$ruleId) {
                 continue;
             }
             try {
                 $rule = $this->rulesFacade->findRule($ruleId);
                 $this->ruleSetsFacade->removeRuleFromRuleSet($rule, $ruleSet);
             } catch (\Exception $e) {
                 continue;
             }
         }
     }
     $this->ruleSetsFacade->updateRuleSetRulesCount($ruleSet);
     $this->resource = ['code' => 200, 'status' => 'ok'];
     $this->sendResource();
 }
 /**
  * Funkce pro načtení PMML
  * @param string $pmml
  * @return bool
  */
 public function parseRulesPMML($pmml)
 {
     $xml = simplexml_load_string($pmml);
     $xml->registerXPathNamespace('guha', 'http://keg.vse.cz/ns/GUHA0.1rev1');
     $guhaAssociationModel = $xml->xpath('//guha:AssociationModel');
     $guhaAssociationModel = $guhaAssociationModel[0];
     /** @var \SimpleXMLElement $associationRulesXml */
     $associationRulesXml = $guhaAssociationModel->AssociationRules;
     if (count($associationRulesXml->AssociationRule) == 0) {
         return true;
     }
     //pokud nejsou vrácena žádná pravidla, nemá smysl zpracovávat cedenty...
     #region zpracování cedentů jen s jedním subcedentem
     $dbaItems = $associationRulesXml->xpath('./DBA[count(./BARef)=1]');
     $alternativeCedentIdsArr = array();
     if (!empty($dbaItems)) {
         foreach ($dbaItems as $dbaItem) {
             $idStr = (string) $dbaItem['id'];
             $BARefStr = (string) $dbaItem->BARef;
             $alternativeCedentIdsArr[$idStr] = isset($alternativeCedentIdsArr[$BARefStr]) ? $alternativeCedentIdsArr[$BARefStr] : $BARefStr;
         }
     }
     if (!empty($alternativeCedentIdsArr)) {
         $repeat = true;
         while ($repeat) {
             $repeat = false;
             foreach ($alternativeCedentIdsArr as $id => $referencedId) {
                 if (isset($alternativeCedentIdsArr[$referencedId])) {
                     $alternativeCedentIdsArr[$id] = $alternativeCedentIdsArr[$referencedId];
                     $repeat = true;
                 }
             }
         }
     }
     #endregion
     /** @var Cedent[] $cedentsArr */
     $cedentsArr = array();
     /** @var RuleAttribute[] $ruleAttributesArr */
     $ruleAttributesArr = array();
     $unprocessedIdsArr = array();
     #region zpracování rule attributes
     $bbaItems = $associationRulesXml->xpath('//BBA');
     if (!empty($bbaItems)) {
         foreach ($bbaItems as $bbaItem) {
             $ruleAttribute = new RuleAttribute();
             //FIXME IMPORTANT změna ukládání ruleAttributes
             //FIXME IMPORTANT podpora většího množství hodnot v rule attribute
             $idStr = (string) $bbaItem['id'];
             $ruleAttribute->field = (string) $bbaItem->FieldRef;
             $ruleAttribute->value = (string) $bbaItem->CatRef;
             $ruleAttributesArr[$idStr] = $ruleAttribute;
             $this->rulesFacade->saveRuleAttribute($ruleAttribute);
         }
     }
     //pročištění pole s alternativními IDčky
     if (!empty($alternativeCedentIdsArr)) {
         foreach ($alternativeCedentIdsArr as $id => $alternativeId) {
             if (isset($ruleAttributesArr[$alternativeId])) {
                 unset($alternativeCedentIdsArr[$id]);
             }
         }
     }
     #endregion
     #region zpracování cedentů s více subcedenty/hodnotami
     $dbaItems = $associationRulesXml->xpath('./DBA[count(./BARef)>0]');
     if (!empty($dbaItems)) {
         do {
             foreach ($dbaItems as $dbaItem) {
                 $idStr = (string) $dbaItem['id'];
                 if (isset($cedentsArr[$idStr])) {
                     continue;
                 }
                 if (isset($alternativeCedentIdsArr[$idStr])) {
                     continue;
                 }
                 if (isset($ruleAttributesArr[$idStr])) {
                     continue;
                 }
                 $process = true;
                 foreach ($dbaItem->BARef as $BARef) {
                     $BARefStr = (string) $BARef;
                     if (isset($alternativeCedentIdsArr[$BARefStr])) {
                         $BARefStr = $alternativeCedentIdsArr[$BARefStr];
                     }
                     if (!isset($cedentsArr[$BARefStr]) && !isset($ruleAttributesArr[$BARefStr])) {
                         $unprocessedIdsArr[$BARefStr] = $BARefStr;
                         $process = false;
                     }
                 }
                 if ($process) {
                     unset($unprocessedIdsArr[$idStr]);
                     //vytvoření konkrétního cedentu...
                     $cedent = new Cedent();
                     if (isset($dbaItem['connective'])) {
                         $cedent->connective = Strings::lower((string) $dbaItem['connective']);
                     } else {
                         $cedent->connective = 'conjunction';
                     }
                     $this->rulesFacade->saveCedent($cedent);
                     $cedentsArr[$idStr] = $cedent;
                     foreach ($dbaItem->BARef as $BARef) {
                         $BARefStr = (string) $BARef;
                         if (isset($alternativeCedentIdsArr[$BARefStr])) {
                             $BARefStr = $alternativeCedentIdsArr[$BARefStr];
                         }
                         if (isset($cedentsArr[$BARefStr])) {
                             $cedent->addToCedents($cedentsArr[$BARefStr]);
                         } elseif (isset($ruleAttributesArr[$BARefStr])) {
                             $cedent->addToRuleAttributes($ruleAttributesArr[$BARefStr]);
                         }
                     }
                     $this->rulesFacade->saveCedent($cedent);
                 } else {
                     $unprocessedIdsArr[$idStr] = $idStr;
                 }
             }
         } while (!empty($unprocessedIdsArr));
     }
     #endregion
     foreach ($associationRulesXml->AssociationRule as $associationRule) {
         $rule = new Rule();
         $rule->task = $this->task;
         if (isset($associationRule['antecedent'])) {
             //jde o pravidlo s antecedentem
             $antecedentId = (string) $associationRule['antecedent'];
             if (isset($alternativeCedentIdsArr[$antecedentId])) {
                 $antecedentId = $alternativeCedentIdsArr[$antecedentId];
             }
             $rule->antecedent = $cedentsArr[$antecedentId];
         } else {
             //jde o pravidlo bez antecedentu
             $rule->antecedent = null;
         }
         $consequentId = (string) $associationRule['consequent'];
         if (isset($alternativeCedentIdsArr[$consequentId])) {
             $consequentId = $alternativeCedentIdsArr[$consequentId];
         }
         $rule->consequent = $cedentsArr[$consequentId];
         $rule->text = (string) $associationRule->Text;
         $fourFtTable = $associationRule->FourFtTable;
         $rule->a = (string) $fourFtTable['a'];
         $rule->b = (string) $fourFtTable['b'];
         $rule->c = (string) $fourFtTable['c'];
         $rule->d = (string) $fourFtTable['d'];
         $this->rulesFacade->saveRule($rule);
     }
     $this->rulesFacade->calculateMissingInterestMeasures();
     return true;
 }
 /**
  * Funkce pro načtení PMML
  * @param string|\SimpleXMLElement $pmml
  * @param int &$rulesCount = null - informace o počtu importovaných pravidel
  * @param bool $updateImportedRulesHeads=false
  * @return bool
  * @throws \Exception
  */
 public function fullParseRulesPMML($pmml, &$rulesCount = null, $updateImportedRulesHeads = false)
 {
     Debugger::log('fullParseRulesPMML start ' . time(), ILogger::DEBUG);
     if ($pmml instanceof \SimpleXMLElement) {
         $xml = $pmml;
     } else {
         $xml = simplexml_load_string($pmml);
     }
     $xml->registerXPathNamespace('guha', 'http://keg.vse.cz/ns/GUHA0.1rev1');
     $guhaAssociationModel = $xml->xpath('//guha:AssociationModel');
     $guhaAssociationModel = $guhaAssociationModel[0];
     $rulesCount = (string) $guhaAssociationModel['numberOfRules'];
     /** @var \SimpleXMLElement $associationRulesXml */
     $associationRulesXml = $guhaAssociationModel->AssociationRules;
     if (count($associationRulesXml->AssociationRule) == 0) {
         return true;
     }
     //pokud nejsou vrácena žádná pravidla, nemá smysl zpracovávat cedenty...
     #region zpracování cedentů jen s jedním subcedentem
     $dbaItems = $associationRulesXml->xpath('./DBA[count(./BARef)=1]');
     $alternativeCedentIdsArr = array();
     if (!empty($dbaItems)) {
         foreach ($dbaItems as $dbaItem) {
             $idStr = (string) $dbaItem['id'];
             $BARefStr = (string) $dbaItem->BARef;
             $alternativeCedentIdsArr[$idStr] = isset($alternativeCedentIdsArr[$BARefStr]) ? $alternativeCedentIdsArr[$BARefStr] : $BARefStr;
         }
     }
     if (!empty($alternativeCedentIdsArr)) {
         do {
             $repeat = false;
             foreach ($alternativeCedentIdsArr as $id => $referencedId) {
                 if (isset($alternativeCedentIdsArr[$referencedId])) {
                     $alternativeCedentIdsArr[$id] = $alternativeCedentIdsArr[$referencedId];
                     $repeat = true;
                 }
             }
         } while ($repeat);
     }
     #endregion
     /** @var Cedent[] $cedentsArr */
     $cedentsArr = [];
     /** @var RuleAttribute[] $ruleAttributesArr */
     $ruleAttributesArr = [];
     /** @var string[] $unprocessedIdsArr */
     $unprocessedIdsArr = [];
     /** @var ValuesBin[]|Value[] $valuesBinsArr */
     $valuesBinsArr = [];
     /** @var Attribute[] $attributesArr - pole indexované pomocí názvů atributů použitých v PMML */
     $attributesArr = $this->miner->metasource->getAttributesByNamesArr();
     #region zpracování rule attributes
     $bbaItems = $associationRulesXml->xpath('//BBA');
     if (!empty($bbaItems)) {
         foreach ($bbaItems as $bbaItem) {
             $ruleAttribute = new RuleAttribute();
             $idStr = (string) $bbaItem['id'];
             //uložení vazby na Attribute
             $attributeName = (string) $bbaItem->FieldRef;
             $valueName = (string) $bbaItem->CatRef;
             $attribute = $attributesArr[$attributeName];
             $ruleAttribute->attribute = $attribute;
             $valueItem = $attribute->preprocessing->findValue($valueName);
             if ($valueItem instanceof Value) {
                 $ruleAttribute->value = $valueItem;
             } elseif ($valueItem instanceof ValuesBin) {
                 $ruleAttribute->valuesBin = $valueItem;
             } elseif ($attribute->preprocessing->specialType == Preprocessing::SPECIALTYPE_EACHONE) {
                 //pokud jde o preprocessing each-one a nebyla nalezena příslušná hodnota v DB, tak ji uložíme
                 $value = new Value();
                 $value->format = $attribute->preprocessing->format;
                 $value->value = $valueName;
                 $this->metaAttributesFacade->saveValue($value);
                 $ruleAttribute->value = $value;
             }
             $this->rulesFacade->saveRuleAttribute($ruleAttribute);
             $ruleAttributesArr[$idStr] = $ruleAttribute;
         }
     }
     //pročištění pole s alternativními IDčky
     if (!empty($alternativeCedentIdsArr)) {
         foreach ($alternativeCedentIdsArr as $id => $alternativeId) {
             if (isset($ruleAttributesArr[$alternativeId])) {
                 unset($alternativeCedentIdsArr[$id]);
             }
         }
     }
     #endregion
     #region zpracování cedentů s více subcedenty/hodnotami
     $dbaItems = $associationRulesXml->xpath('./DBA[count(./BARef)>0]');
     if (!empty($dbaItems)) {
         do {
             foreach ($dbaItems as $dbaItem) {
                 $idStr = (string) $dbaItem['id'];
                 if (isset($cedentsArr[$idStr])) {
                     continue;
                 }
                 if (isset($alternativeCedentIdsArr[$idStr])) {
                     continue;
                 }
                 if (isset($ruleAttributesArr[$idStr])) {
                     continue;
                 }
                 $process = true;
                 foreach ($dbaItem->BARef as $BARef) {
                     $BARefStr = (string) $BARef;
                     if (isset($alternativeCedentIdsArr[$BARefStr])) {
                         $BARefStr = $alternativeCedentIdsArr[$BARefStr];
                     }
                     if (!isset($cedentsArr[$BARefStr]) && !isset($ruleAttributesArr[$BARefStr])) {
                         $unprocessedIdsArr[$BARefStr] = $BARefStr;
                         $process = false;
                     }
                 }
                 if ($process) {
                     unset($unprocessedIdsArr[$idStr]);
                     //vytvoření konkrétního cedentu...
                     $cedent = new Cedent();
                     if (isset($dbaItem['connective'])) {
                         $cedent->connective = Strings::lower((string) $dbaItem['connective']);
                     } else {
                         $cedent->connective = 'conjunction';
                     }
                     $this->rulesFacade->saveCedent($cedent);
                     $cedentsArr[$idStr] = $cedent;
                     foreach ($dbaItem->BARef as $BARef) {
                         $BARefStr = (string) $BARef;
                         if (isset($alternativeCedentIdsArr[$BARefStr])) {
                             $BARefStr = $alternativeCedentIdsArr[$BARefStr];
                         }
                         if (isset($cedentsArr[$BARefStr])) {
                             $cedent->addToCedents($cedentsArr[$BARefStr]);
                         } elseif (isset($ruleAttributesArr[$BARefStr])) {
                             $cedent->addToRuleAttributes($ruleAttributesArr[$BARefStr]);
                         }
                     }
                     $this->rulesFacade->saveCedent($cedent);
                 } else {
                     $unprocessedIdsArr[$idStr] = $idStr;
                 }
             }
         } while (!empty($unprocessedIdsArr));
     }
     #endregion
     #region association rules
     /** @var Cedent[] $topCedentsArr - pole s cedenty na vrcholné úrovni (pokud je ruleAttribute přímo na vrcholné úrovni, musí být zabalen v cedentu)*/
     $topCedentsArr = array();
     foreach ($associationRulesXml->AssociationRule as $associationRule) {
         $rule = false;
         if ($updateImportedRulesHeads) {
             try {
                 $rule = $this->rulesFacade->findRuleByPmmlImportId($this->task->taskId, (string) $associationRule['id']);
             } catch (\Exception $e) {
                 /*ignore*/
             }
         }
         if (!$rule) {
             $rule = new Rule();
         }
         $rule->task = $this->task;
         #region antecedent
         if (isset($associationRule['antecedent'])) {
             //jde o pravidlo s antecedentem
             $antecedentId = (string) $associationRule['antecedent'];
             if (isset($alternativeCedentIdsArr[$antecedentId])) {
                 $antecedentId = $alternativeCedentIdsArr[$antecedentId];
             }
             if (isset($cedentsArr[$antecedentId])) {
                 $rule->antecedent = $cedentsArr[$antecedentId];
             } else {
                 if (isset($ruleAttributesArr[$antecedentId])) {
                     if (!isset($topCedentsArr[$antecedentId])) {
                         $cedent = new Cedent();
                         $cedent->connective = 'conjunction';
                         $this->rulesFacade->saveCedent($cedent);
                         $topCedentsArr[$antecedentId] = $cedent;
                         $cedent->addToRuleAttributes($ruleAttributesArr[$antecedentId]);
                         $this->rulesFacade->saveCedent($cedent);
                     }
                     $rule->antecedent = $topCedentsArr[$antecedentId];
                 } else {
                     throw new \Exception('Import failed!');
                 }
             }
         } else {
             //jde o pravidlo bez antecedentu
             $rule->antecedent = null;
         }
         #endregion antecedent
         #region consequent
         $consequentId = (string) $associationRule['consequent'];
         if (isset($alternativeCedentIdsArr[$consequentId])) {
             $consequentId = $alternativeCedentIdsArr[$consequentId];
         }
         if (isset($cedentsArr[$consequentId])) {
             $rule->consequent = $cedentsArr[$consequentId];
         } else {
             if (isset($ruleAttributesArr[$consequentId])) {
                 if (!isset($topCedentsArr[$consequentId])) {
                     $cedent = new Cedent();
                     $cedent->connective = 'conjunction';
                     $this->rulesFacade->saveCedent($cedent);
                     $topCedentsArr[$consequentId] = $cedent;
                     $cedent->addToRuleAttributes($ruleAttributesArr[$consequentId]);
                     $this->rulesFacade->saveCedent($cedent);
                 }
                 $rule->consequent = $topCedentsArr[$consequentId];
             } else {
                 throw new \Exception('Import failed!');
             }
         }
         #endregion consequent
         $rule->text = (string) $associationRule->Text;
         $fourFtTable = $associationRule->FourFtTable;
         $rule->a = (string) $fourFtTable['a'];
         $rule->b = (string) $fourFtTable['b'];
         $rule->c = (string) $fourFtTable['c'];
         $rule->d = (string) $fourFtTable['d'];
         $this->rulesFacade->saveRule($rule);
     }
     $this->rulesFacade->calculateMissingInterestMeasures($this->task);
     #endregion association rules
     Debugger::log('fullParseRulesPMML end ' . time(), ILogger::DEBUG);
     return true;
 }