Source for file InfModelF.php

Documentation is available at InfModelF.php

  1. <?php
  2. // ----------------------------------------------------------------------------------
  3. // Class: InfModelF
  4. // ----------------------------------------------------------------------------------
  5.  
  6. /**
  7. * A InfModelF extends the InfModel Class, with a forward chaining algorithm.
  8. * If a new statement is added, it is enferd at
  9. * once and all the entailed statements are added too.
  10. * When adding or removing a statement, that produced a new inference rule,
  11. * all entailed statements are discarded and the whole base model is infered
  12. * again.
  13. * The InfModelF is safe for loops in Ontologies, that would cause infinite loops.
  14. *
  15. @version  $Id: fsource_infModel__infModelInfModelF.php.html 443 2007-06-01 16:25:38Z cax $
  16. @author Daniel Westphal <mail at d-westphal dot de>
  17.  
  18. *
  19. @package infModel
  20. @access    public
  21. ***/
  22.  
  23. class InfModelF extends InfModel 
  24. {
  25.  
  26.     /**
  27.     * Array that holds the position of the infered statements in the model.
  28.     *
  29.     * @var        array 
  30.     * @access    private
  31.     */    
  32.     var $infPos;
  33.     
  34.     
  35.     /**
  36.     * Variable that influences the habbit when adding statements.
  37.     * Used by the loadModel method to increase performance.
  38.     *
  39.     * @var        boolean 
  40.     * @access    private
  41.     */
  42.     var $inferenceEnabled;
  43.     
  44.         
  45.        /**
  46.     * Constructor
  47.     * You can supply a base_uri.
  48.     *
  49.     * @param string $baseURI 
  50.     * @access    public
  51.     */        
  52.     function InfModelF($baseURI NULL)
  53.     {
  54.         parent::InfModel($baseURI);
  55.         $this->infPos=array();
  56.         $this->inferenceEnabled=true;    
  57.     }
  58.  
  59.     /**
  60.     * Adds a new triple to the MemModel without checking if the statement
  61.     * is already in the MemModel.
  62.     * So if you want a duplicate free MemModel use the addWithoutDuplicates()
  63.     * function (which is slower then add())
  64.     * The statement is infered and all entailed statements are added.
  65.     *
  66.     * @param    object Statement    $statement 
  67.     * @access    public
  68.     * @throws    PhpError
  69.     */
  70.     function add ($statement)
  71.     {
  72.         parent::add($statement);
  73.         if ($this->inferenceEnabled)
  74.         {
  75.             foreach ($this->entailStatement($statementas $state)
  76.             {
  77.                 //a addWithoutDublicates construct
  78.                 if(!$this->contains($state))
  79.                 {
  80.             
  81.                     parent::add($state);
  82.                     //save the position of the infered statements
  83.                     end($this->triples);
  84.                     $this->infPos[]=key($this->triples);
  85.                 };
  86.             }
  87.         //apply the complete inference to the model, if the added statement was able to add a rule
  88.         if (in_array($statement->getLabelPredicate(),$this->supportedInference))
  89.             $this->applyInference();
  90.         }
  91.     }
  92.     
  93.  
  94.     /**
  95.     * Checks if a new statement is already in the MemModel and adds
  96.     * the statement, if it is not in the MemModel.
  97.     * addWithoutDuplicates() is significantly slower then add().
  98.     * Retruns TRUE if the statement is added.
  99.     * FALSE otherwise.
  100.     * The statement is infered and all entailed statements are added.
  101.     *
  102.     * @param    object Statement    $statement 
  103.     * @return   boolean 
  104.     * @access    public
  105.     * @throws    PhpError
  106.     */    
  107.      function addWithoutDuplicates($statement
  108.      {
  109.         if(!$this->contains($statement))
  110.         {
  111.              parent::add($statement);
  112.              if ($this->inferenceEnabled)
  113.              {
  114.                 foreach ($this->entailStatement($statementas $statement)
  115.                 {
  116.                     if(!$this->contains($statement))
  117.                         {
  118.                             parent::add($statement);
  119.                             //save the position of the infered statements
  120.                             end($this->triples);
  121.                             $this->infPos[]=key($this->triples);
  122.                         };
  123.                 };
  124.             if (in_array($statement->getLabelPredicate(),$this->supportedInference))
  125.                 $this->applyInference();
  126.              }
  127.             return true;
  128.          }
  129.          return false;
  130.      }
  131.  
  132.     
  133.  
  134.     /**
  135.     * Entails every statement and adds the entailments if not already
  136.     * in the model.
  137.     *
  138.     * @access    private
  139.     */        
  140.     function applyInference()
  141.     {
  142.         //check every statement in the model
  143.         foreach ($this->triples as $statement)
  144.         {
  145.             //gat all statements, that it recursively entails
  146.             foreach ($this->entailStatement($statementas $statement)
  147.             {
  148.                 if (!$this->contains($statement))
  149.                 {
  150.                     parent::add($statement);
  151.                     //add the InfStatement position to the index
  152.                     end($this->triples);
  153.                     $this->infPos[]=key($this->triples);
  154.                 };
  155.             };
  156.         };
  157.     }
  158.     
  159.  
  160.     /**
  161.     * Entails a statement by recursively using the _entailStatementRec
  162.     * method.
  163.     * 
  164.     * @param    object Statement    $statement 
  165.     * @return   array of statements
  166.     * @access    public
  167.     */            
  168.     function entailStatement ($statement)
  169.     {
  170.         $infStatementsIndex=array();
  171.         return $this->_entailStatementRec($statement,$infStatementsIndex);
  172.     }
  173.  
  174.     /**
  175.     * Recursive method, that checks the statement with the trigger of
  176.     * every rule. If the trigger matches and entails new statements,
  177.     * those statements are recursively infered too.
  178.     * The $infStatementsIndex array holds lready infered statements
  179.     * to prevent infinite loops.
  180.     *
  181.     * 
  182.     * @param    object Statement $statement 
  183.     * @param    array $infStatementsIndex 
  184.     * @return   array of statements
  185.     * @access    private
  186.     */
  187.     function _entailStatementRec $statement,$infStatementsIndex)
  188.     {
  189.         $infStatements array();
  190.         $return array();
  191.         
  192.         //dont entail statements about the supported inference-schema
  193.         if (!in_array($statement->getLabelPredicate(),$this->supportedInference))
  194.         {
  195.             //check only the rules, that were returned by the index
  196.             foreach ($this->_findRuleTriggerInIndex($statementas $key )
  197.             {
  198.                 $infRule=$this->infRules[$key];
  199.     
  200.                 $stateString=$key.serialize($statement);
  201.                 //If the statement wasn't infered before
  202.                 if (!in_array($stateString,$infStatementsIndex))
  203.                 {
  204.                     $infStatementsIndex[]=$stateString;
  205.                     //Check, if the Statements triggers this rule
  206.                     if($infRule->checkTrigger($statement))
  207.                     {
  208.                         $infStatement=$infRule->entail($statement);
  209.                         #if(!$this->contains($infStatement))
  210.                         {
  211.                             $return[]=$infStatement;
  212.                             $return=array_merge($return,
  213.                                                 $this->_entailStatementRec($infStatement
  214.                                                                             $infStatementsIndex));
  215.                         };    
  216.                                                                         
  217.                     };
  218.                 };
  219.             };
  220.         };    
  221.         return $return;
  222.     }
  223.     
  224.     /**
  225.     * Removes all infered statements from the model but keeps the
  226.     * infernece rules.
  227.     *
  228.     * @access    public
  229.     */     
  230.     function removeInfered()
  231.     {
  232.         $indexTmp=$this->indexed;
  233.         $this->index(-1);
  234.         foreach ($this->infPos as $key)
  235.         {
  236.             unset($this->triples[$key]);
  237.         };
  238.         $this->infPos=array();
  239.         $this->index($indexTmp);
  240.     }    
  241.      
  242.      
  243.     /**
  244.     * Load a model from a file containing RDF, N3 or N-Triples.
  245.     * This function recognizes the suffix of the filename (.n3 or .rdf) and
  246.     * calls a suitable parser, if no $type is given as string
  247.     * ("rdf" "n3" "nt");
  248.     * If the model is not empty, the contents of the file is added to
  249.     * this DbModel.
  250.     *
  251.     * While loading the model, the inference entailing is disabled, but
  252.     * new inference rules are added to increase performance.
  253.     * 
  254.     * @param     string     $filename 
  255.     * @param     string     $type 
  256.     * @access    public
  257.     */
  258.     function load($filename$type NULL
  259.     {
  260.         //Disable entailing to increase performance
  261.          $this->inferenceEnabled=false;
  262.          parent::load($filename$type);
  263.          //Enable entailing
  264.          $this->inferenceEnabled=true;
  265.          //Entail all statements
  266.          $this->applyInference();
  267.      }
  268.     
  269.     /**
  270.     * Short Dump of the InfModelF.
  271.     *
  272.     * @access    public
  273.     * @return    string 
  274.     */  
  275.     function toString({
  276.        return 'InfModelF[baseURI=' $this->getBaseURI(';  
  277.                    size=' $this->size(true']';
  278.     }
  279.         
  280.     /**
  281.     * Create a MemModel containing all the triples (including inferred
  282.     * statements) of the current InfModelF.
  283.     *
  284.     * @return object MemModel 
  285.     * @access public
  286.     */
  287.     function getMemModel(
  288.     {
  289.         $returnnew MemModel();
  290.         $return->setBaseURI($this->baseURI);
  291.         foreach ($this->triples as $statement)
  292.             $return->add($statement);
  293.         
  294.         $return->addParsedNamespaces($this->getParsedNamespaces());    
  295.         return $return;
  296.     }
  297.       
  298.     /**
  299.     * Create a MemModel containing only the base triples
  300.     * (without inferred statements) of the current InfModelF.
  301.     *
  302.     * @return object MemModel 
  303.     * @access public
  304.     */
  305.     function  getBaseMemModel(
  306.     {
  307.         $returnnew MemModel();
  308.         $return->setBaseURI($this->baseURI);
  309.         foreach ($this->triples as $key => $statement)
  310.             if (!in_array($key,$this->infPos))
  311.                 $return->add($statement);
  312.         $retun->addParsedNamespaces($this->getParsedNamespaces());
  313.         return $return;
  314.     }
  315.     
  316.     
  317.     /**
  318.     * Removes the triple from the MemModel.
  319.     * TRUE if the triple is removed.
  320.     * FALSE otherwise.
  321.     *
  322.     * Checks, if it touches any statements, that added inference rules
  323.     * to the model
  324.     *
  325.     * @param    object Statement    $statement 
  326.     * @return   boolean 
  327.     * @access    public
  328.     * @throws    PhpError
  329.     */
  330.     function remove($statement)
  331.     {
  332.         //If the statement is in the model
  333.         if($this->contains($statement))
  334.         {
  335.             $inferenceRulesWereTouched=false;
  336.             //If the statement was able to add inference rules
  337.             if (in_array($statement->getLabelPredicate(),$this->supportedInference))
  338.             {
  339.                 $statementPositions=$this->_removeFromInference($statement);
  340.                 $inferenceRulesWereTouched=true;
  341.             else 
  342.             //get the position of all matching statements
  343.             {
  344.                 $statementPositions=array();
  345.                 //find the positions of the statements
  346.                 $statementPosition=-1;
  347.                 do
  348.                 {
  349.                     
  350.                     $statementPosition =
  351.                     $this->findFirstMatchOff($statement->getSubject(),
  352.                                                 $statement->getPredicate(),
  353.                                                 $statement->getObject(),
  354.                                                 $statementPosition+1);
  355.                                                 
  356.                     if ($statementPosition!=-1)
  357.                         $statementPositions[]=$statementPosition;                            
  358.                                                 
  359.                 }    while ($statementPosition != -1);            
  360.             }
  361.             
  362.             //remove matching statements
  363.             parent::remove($statement);
  364.             foreach ($statementPositions as $statementPosition)
  365.             {
  366.                 //if the statement was infered, remove it from the index of the infered statements.
  367.                 if (in_array($statementPosition,$this->infPos))
  368.                     unset ($this->infPos[$statementPosition]);
  369.             }
  370.             if ($inferenceRulesWereTouched)
  371.             {
  372.                 //remove the statement and re-entail the model
  373.                 $this->removeInfered();
  374.                 $this->applyInference();
  375.             }
  376.             return true;
  377.         else 
  378.         {
  379.             return false;    
  380.         }
  381.     }
  382.     
  383.     /** 
  384.     * Adds another model to this MemModel.
  385.     * Duplicate statements are not removed.
  386.     * If you don't want duplicates, use unite().
  387.     * If any statement of the model to be added to this model contains a blankNode
  388.     * with an identifier already existing in this model, a new blankNode is generated.
  389.     *
  390.     * @param    object Model    $model 
  391.     * @access    public
  392.     * @throws phpErrpr
  393.     *
  394.     */
  395.     function addModel(&$model)  
  396.     {
  397.         //Disable entailing to increase performance
  398.          $this->inferenceEnabled=false;
  399.          parent::addModel($model);
  400.          //Enable entailing
  401.          $this->inferenceEnabled=true;
  402.          //Entail all statements
  403.          $this->applyInference();
  404.     }
  405. };
  406. ?>

Documentation generated on Fri, 1 Jun 2007 16:49:31 +0200 by phpDocumentor 1.3.2