Source for file MemModel.php

Documentation is available at MemModel.php

  1. <?php
  2. require_once RDFAPI_INCLUDE_DIR 'model/Model.php';
  3. // ----------------------------------------------------------------------------------
  4. // Class: MemModel
  5. // ----------------------------------------------------------------------------------
  6.  
  7. /**
  8. * A MemModel is an RDF Model, which is stored in the main memory.
  9. * This class provides methods for manipulating MemModels.
  10. *
  11. *
  12. *
  13. @version  $Id: fsource_model__modelMemModel.php.html 443 2007-06-01 16:25:38Z cax $
  14. @author Chris Bizer <chris@bizer.de>
  15. @author Gunnar AAstrand Grimnes <ggrimnes@csd.abdn.ac.uk>
  16. @author Radoslaw Oldakowski <radol@gmx.de>
  17. @author Daniel Westphal <mail@d-westphal.de>
  18. @author Tobias Gauß <tobias.gauss@web.de>
  19. *
  20. @package model
  21. @access    public
  22. */
  23.  
  24. class MemModel extends Model {
  25.  
  26.     /**
  27.     * Triples of the MemModel
  28.     * @var        array 
  29.     * @access    private
  30.     */
  31.     var $triples array();
  32.  
  33.     /**
  34.     * Array containing the search indices
  35.     * @var        array['INDEX_TYPE'][]['label'][]['PosInModel'] 
  36.     *
  37.     * @access   private
  38.     */
  39.     var $indexArr ;
  40.  
  41.  
  42.     /**
  43.     * depending on which index is used this variable is -1,0,1,2 or 3
  44.     *
  45.     * -1 : no index
  46.     *  0 : default indices over subject, predicate, object separate
  47.     *  1 : index over subject+predicate+object
  48.     *  2 : index over subject+predicate
  49.     *  3 : index over subject+object
  50.     *
  51.     * @var        int 
  52.     * @access    private
  53.     */
  54.     var $indexed;
  55.  
  56.  
  57.  
  58.     /**
  59.     * Array of namespaces
  60.     *
  61.     * @var     array 
  62.     * @access    private
  63.     */
  64.     var $parsedNamespaces=array();
  65.  
  66.  
  67.  
  68.     /**
  69.     * Constructor
  70.     * You can supply a base_uri
  71.     *
  72.     * @param string $baseURI 
  73.     * @access    public
  74.     */
  75.     function MemModel($baseURI NULL{
  76.         $this->setBaseURI($baseURI);
  77.         $this->indexed INDEX_TYPE;
  78.     }
  79.  
  80.     /**
  81.     * Set a base URI for the MemModel.
  82.     * Affects creating of new resources and serialization syntax.
  83.     * If the URI doesn't end with # : or /, then a # is added to the URI.
  84.     * @param    string    $uri 
  85.     * @access    public
  86.     */
  87.     function setBaseURI($uri{
  88.  
  89.         if ($uri != NULL{
  90.             $c substr($uristrlen($uri)-,1);
  91.             if (!($c=='#' || $c==':' || $c=='/' || $c=="\\"))
  92.             $uri .= '#';
  93.         }
  94.         $this->baseURI $uri;
  95.     }
  96.  
  97.  
  98.     /**
  99.     * Number of triples in the MemModel
  100.     *
  101.     * @return    integer 
  102.     * @access    public
  103.     */
  104.     function size({
  105.         return count($this->triples);
  106.     }
  107.  
  108.     /**
  109.     * Checks if MemModel is empty
  110.     *
  111.     * @return    boolean 
  112.     * @access    public
  113.     */
  114.     function isEmpty({
  115.         if (count($this->triples== 0{
  116.             return TRUE;
  117.         else {
  118.             return FALSE;
  119.         };
  120.     }
  121.  
  122.  
  123.     /**
  124.     * Adds a new triple to the MemModel without checking if the statement is already in the MemModel.
  125.     * So if you want a duplicate free MemModel use the addWithoutDuplicates() function (which is slower then add())
  126.     *
  127.     * @param        object Statement    $statement 
  128.     * @access    public
  129.     * @throws    PhpError
  130.     */
  131.     function add($statement{
  132.         if (!is_a($statement'Statement')) {
  133.             $errmsg RDFAPI_ERROR '(class: MemModel; method: add): Statement expected.';
  134.             trigger_error($errmsgE_USER_ERROR);
  135.         }
  136.  
  137.         if($this->indexed != -1){
  138.             $this->triples[$statement;
  139.             end($this->triples);
  140.             $k=key($this->triples);
  141.             if($this->indexed==0){
  142.                 // index over S
  143.                 $this->_indexOpr($statement,$k,4,1);
  144.                 // index over P
  145.                 $this->_indexOpr($statement,$k,5,1);
  146.                 // index over O
  147.                 $this->_indexOpr($statement,$k,6,1);
  148.             }else{
  149.                 $this->_indexOpr($statement,$k,$this->indexed,1);
  150.             }
  151.  
  152.         }else{
  153.             $this->triples[$statement;
  154.         }
  155.     }
  156.  
  157.  
  158.  
  159.     /**
  160.     * Checks if a new statement is already in the MemModel and adds the statement, if it is not in the MemModel.
  161.     * addWithoutDuplicates() is significantly slower then add().
  162.     * Retruns TRUE if the statement is added.
  163.     * FALSE otherwise.
  164.     *
  165.     * @param    object Statement    $statement 
  166.     * @return    boolean 
  167.     * @access    public
  168.     * @throws    PhpError
  169.     */
  170.     function addWithoutDuplicates($statement{
  171.  
  172.         if (!is_a($statement'Statement')) {
  173.             $errmsg RDFAPI_ERROR '(class: MemModel; method: addWithoutDuplicates): Statement expected.';
  174.             trigger_error($errmsgE_USER_ERROR);
  175.         }
  176.  
  177.         if (!$this->contains($statement)) {
  178.             $this->add($statement);
  179.             return true;
  180.         }else{
  181.             return false;
  182.         }
  183.     }
  184.  
  185.     /**
  186.     * Removes the triple from the MemModel.
  187.     * TRUE if the triple is removed.
  188.     * FALSE otherwise.
  189.     *
  190.     * @param        object Statement    $statement 
  191.     * @return    boolean 
  192.     * @access    public
  193.     * @throws    PhpError
  194.     */
  195.     function remove($statement{
  196.  
  197.         if (!is_a($statement'Statement')) {
  198.             $errmsg RDFAPI_ERROR '(class: MemModel; method: remove): Statement expected.';
  199.             trigger_error($errmsgE_USER_ERROR);
  200.         }
  201.         if($this->indexed==-1){
  202.             $pass=false;
  203.             foreach($this->triples as $key => $value{
  204.                 if ($this->matchStatement($value$statement->subject()$statement->predicate()$statement->object())) {
  205.                     unset($this->triples[$key]);
  206.                     $passtrue;
  207.                 }
  208.             }
  209.             return $pass;
  210.         }else{
  211.             $knull;
  212.             if($this->indexed==0){
  213.                 $pass=false;
  214.                 $del=false;
  215.                 while($del!=-1){
  216.                     // index over S
  217.                     $del=$this->_indexOpr($statement,$k,4,0);
  218.                     // index over P
  219.                     $this->_indexOpr($statement,$k,5,0);
  220.                     // index over O
  221.                     $this->_indexOpr($statement,$k,6,0);
  222.                     if($del!=-1){
  223.                         unset($this->triples[$del]);
  224.                         $pass=true;
  225.                     }
  226.                 }
  227.                 return $pass;
  228.             }else{
  229.                 $pass=false;
  230.                 $del=false;
  231.                 while($del!=-1){
  232.                     $del=$this->_indexOpr($statement,$k,$this->indexed,0);
  233.                     if($del!=-1){
  234.                         unset($this->triples[$del]);
  235.                         $pass=true;
  236.                     }
  237.                 }
  238.                 return $pass;
  239.             }
  240.         }
  241.     }
  242.  
  243.     /**
  244.     * Short Dump of the MemModel.
  245.     *
  246.     * @access    public
  247.     * @return    string 
  248.     */
  249.     function toString({
  250.         return 'MemModel[baseURI=' $this->getBaseURI(';  size=' $this->size(']';
  251.     }
  252.  
  253.     /**
  254.     * Dumps of the MemModel including all triples.
  255.     *
  256.     * @access    public
  257.     * @return    string 
  258.     */
  259.     function toStringIncludingTriples({
  260.         $dump $this->toString(chr(13);
  261.         foreach($this->triples as $value{
  262.             $dump .= $value->toString(chr(13);
  263.         }
  264.         return $dump;
  265.     }
  266.  
  267.  
  268.  
  269.  
  270.     /**
  271.     * Writes the RDF serialization of the MemModel as HTML.
  272.     *
  273.     * @access    public
  274.     */
  275.     function writeAsHtml({
  276.         require_once(RDFAPI_INCLUDE_DIR.PACKAGE_SYNTAX_RDF);
  277.         $ser new RdfSerializer();
  278.         $rdf =$ser->serialize($this);
  279.         $rdf htmlspecialchars($rdfENT_QUOTES);
  280.         $rdf str_replace(' ''&nbsp;'$rdf);
  281.         $rdf nl2br($rdf);
  282.         echo $rdf;
  283.     }
  284.  
  285.     /**
  286.     * Writes the RDF serialization of the MemModel as HTML table.
  287.     *
  288.     * @access    public
  289.     */
  290.     function writeAsHtmlTable({
  291.         // Import Package Utility
  292.         include_once(RDFAPI_INCLUDE_DIR.PACKAGE_UTILITY);
  293.         RDFUtil::writeHTMLTable($this);
  294.     }
  295.  
  296.  
  297.     /**
  298.     * Writes the RDF serialization of the MemModel as HTML table.
  299.     *
  300.     * @access    public
  301.     * @return    string 
  302.     */
  303.     function writeRdfToString({
  304.         // Import Package Syntax
  305.         include_once(RDFAPI_INCLUDE_DIR.PACKAGE_SYNTAX_RDF);
  306.         $ser new RdfSerializer();
  307.         $rdf =$ser->serialize($this);
  308.         return $rdf;
  309.     }
  310.  
  311.  
  312.     /**
  313.     * Saves the RDF,N3 or N-Triple serialization of the MemModel to a file.
  314.     * You can decide to which format the model should be serialized by using a
  315.     * corresponding suffix-string as $type parameter. If no $type parameter
  316.     * is placed this method will serialize the model to XML/RDF format.
  317.     * Returns FALSE if the MemModel couldn't be saved to the file.
  318.     *
  319.     * @access    public
  320.     * @param     string     $filename 
  321.     * @param     string     $type 
  322.     * @throws   PhpError
  323.     * @return    boolean 
  324.     */
  325.     function saveAs($filename$type ='rdf'{
  326.  
  327.  
  328.         // get suffix and create a corresponding serializer
  329.         if ($type=='rdf'{
  330.             // Import Package Syntax
  331.             include_once(RDFAPI_INCLUDE_DIR.PACKAGE_SYNTAX_RDF);
  332.             $ser=new RdfSerializer();
  333.         }elseif ($type=='nt'{
  334.             // Import Package Syntax
  335.             include_once(RDFAPI_INCLUDE_DIR.PACKAGE_SYNTAX_N3);
  336.             $ser=new NTripleSerializer();
  337.         }elseif ($type=='n3'{
  338.             // Import Package Syntax
  339.             include_once(RDFAPI_INCLUDE_DIR.PACKAGE_SYNTAX_N3);
  340.             $ser=new N3Serializer();
  341.         }else {
  342.             print ('Serializer type not properly defined. Use the strings "rdf","n3" or "nt".');
  343.             return false;
  344.         };
  345.  
  346.         return $ser->saveAs($this$filename);
  347.     }
  348.  
  349.  
  350.     /**
  351.     * Tests if the MemModel contains the given triple.
  352.     * TRUE if the triple belongs to the MemModel;
  353.     * FALSE otherwise.
  354.     *
  355.     * @param    object Statement    &$statement 
  356.     * @return    boolean 
  357.     * @access    public
  358.     */
  359.     function contains(&$statement{
  360.  
  361.         // no index ->linear contains
  362.         if ($this->indexed==-1){
  363.             foreach($this->triples as $value{
  364.                 if ($value->equals($statement)){
  365.                     return TRUE}
  366.             }
  367.             return false;
  368.         }
  369.         if ($this->indexed==0){
  370.             $res $this->_containsIndex($statement,4);
  371.             return $res;
  372.         }else{
  373.             return $this->_containsIndex($statement,$this->indexed);
  374.         }
  375.     }
  376.  
  377.  
  378.     /**
  379.     * Determine if all of the statements in a model are also contained in this MemModel.
  380.     * True if all of the statements in $model are also contained in this MemModel and false otherwise.
  381.     *
  382.     * @param    object Model    &$model 
  383.     * @return    boolean 
  384.     * @access    public
  385.     */
  386.     function containsAll(&$model{
  387.  
  388.         if (is_a($model'MemModel')) {
  389.  
  390.             foreach($model->triples as $statement)
  391.             if(!$this->contains($statement))
  392.             return FALSE;
  393.             return TRUE;
  394.  
  395.         }elseif (is_a($model'DbModel'))
  396.  
  397.         return $model->containsAll($this);
  398.  
  399.         $errmsg RDFAPI_ERROR '(class: MemModel; method: containsAll): Model expected.';
  400.         trigger_error($errmsgE_USER_ERROR);
  401.     }
  402.  
  403.     /**
  404.     * Determine if any of the statements in a model are also contained in this MemModel.
  405.     * True if any of the statements in $model are also contained in this MemModel and false otherwise.
  406.     *
  407.     * @param    object Model    &$model 
  408.     * @return    boolean 
  409.     * @access    public
  410.     */
  411.     function containsAny(&$model{
  412.  
  413.         if (is_a($model'MemModel')) {
  414.  
  415.             foreach($model->triples as $modelStatement)
  416.             if($this->contains($modelStatement))
  417.             return TRUE;
  418.             return FALSE;
  419.  
  420.         }elseif (is_a($model'DbModel'))
  421.  
  422.         return $model->containsAny($this);
  423.  
  424.         $errmsg RDFAPI_ERROR '(class: MemModel; method: containsAll): Model expected.';
  425.         trigger_error($errmsgE_USER_ERROR);
  426.     }
  427.  
  428.  
  429.     /**
  430.     * Builds a search index for the statements in the MemModel.
  431.     * The index is used by the find(),contains(),add() and remove() functions.
  432.     * Performance example using a model with 43000 statements on a Linux machine:
  433.     * Find without index takes 1.7 seconds.
  434.     * Indexing takes 1.8 seconds.
  435.     * Find with index takes 0.001 seconds.
  436.     * So if you want to query a model more then once, build a index first.
  437.     * The defaultindex is indices over subject, predicate, object seperate.
  438.     *
  439.     * mode = 0    : indices over subject,predicate,object (default)
  440.     * mode = 1     : index over subject+predicate+object
  441.     * mode = 2      : index over subject+predicate
  442.     * mode = 3     : index over subject+object
  443.     *
  444.     * @param     int $mode 
  445.     * @access    public
  446.     */
  447.     function index($mode{
  448.  
  449.         unset($this->indexArr);
  450.         $this->indexArr=array();
  451.         switch($mode){
  452.             // unset indices
  453.             case -1:
  454.             $this->indexed=-1;
  455.             unset($this->indexArr);
  456.             break;
  457.             // index over SPO
  458.             case 0:
  459.             $this->indexed=0;
  460.             foreach($this->triples as $k => $t{
  461.                 // index over S
  462.                 $this->_indexOpr($t,$k,4,1);
  463.                 // index over P
  464.                 $this->_indexOpr($t,$k,5,1);
  465.                 // index over O
  466.                 $this->_indexOpr($t,$k,6,1);
  467.             }
  468.             break;
  469.             default:
  470.             $this->indexed=$mode;
  471.             foreach($this->triples as $k => $t{
  472.                 $this->_indexOpr($t,$k,$this->indexed,1);
  473.             }
  474.             break;
  475.         }
  476.     }
  477.  
  478.  
  479.     /**
  480.     * Returns     true if there is an index, false if not.
  481.     *
  482.     * @return    boolean 
  483.     * @access    public
  484.     */
  485.     function isIndexed({
  486.         if($this->indexed!=-1){
  487.             return TRUE;
  488.         }else{
  489.             return FALSE;
  490.         }
  491.     }
  492.  
  493.     /**
  494.     * Returns the indextype:
  495.     * -1 if there is no index, 0 if there are indices over S,P,O(separate),
  496.     * 1 if there is an index over SPO, 2 if there is an index over SP and 3 if
  497.     * there is an index over SO.
  498.     *
  499.     * @return int 
  500.     * @access public
  501.     *
  502.     */
  503.     function getIndexType(){
  504.         return $this->indexed;
  505.     }
  506.  
  507.     /**
  508.     * General method to search for triples.
  509.     * NULL input for any parameter will match anything.
  510.     * Example:  $result = $m->find( NULL, NULL, $node );
  511.     * Finds all triples with $node as object.
  512.     * Returns an empty MemModel if nothing is found.
  513.     *
  514.     * @param    object Node    $subject 
  515.     * @param    object Node    $predicate 
  516.     * @param    object Node    $object 
  517.     * @return    object MemModel 
  518.     * @access    public
  519.     * @throws    PhpError
  520.     */
  521.  
  522.     function find($subject,$predicate,$object{
  523.  
  524.         if (
  525.         (!is_a($subject'Resource'&& $subject != NULL||
  526.         (!is_a($predicate'Resource'&& $predicate != NULL||
  527.         (!is_a($object'Node'&& $object != NULL)
  528.         {
  529.             $errmsg RDFAPI_ERROR '(class: MemModel; method: find): Parameters must be subclasses of Node or NULL';
  530.             trigger_error($errmsgE_USER_ERROR);
  531.         }
  532.  
  533.         $res new MemModel($this->getBaseURI());
  534.         $res->indexed=-1;
  535.  
  536.         if($this->isEmpty())
  537.         return $res;
  538.  
  539.         if($subject == NULL && $predicate == NULL && $object == NULL)
  540.         return $this;
  541.  
  542.         switch($this->indexed){
  543.             case 1:
  544.             if($subject!=NULL && $predicate != NULL && $object != NULL){
  545.                 $pos=$subject->getLabel().$predicate->getLabel().$object->getLabel();
  546.                 return $this->_findInIndex($pos,$subject,$predicate,$object,1);
  547.             }else{
  548.                 break;
  549.             }
  550.  
  551.             case 2:
  552.             if($subject!=NULL && $predicate != NULL){
  553.                 $pos=$subject->getLabel().$predicate->getLabel();
  554.                 return $this->_findInIndex($pos,$subject,$predicate,$object,2);
  555.             }else{
  556.                 break;
  557.             }
  558.  
  559.             case 3:
  560.             if($subject!=NULL && $object != NULL){
  561.                 $pos=$subject->getLabel().$object->getLabel();
  562.                 return $this->_findInIndex($pos,$subject,$predicate,$object,3);
  563.             }else{
  564.                 break;
  565.             }
  566.             case 0:
  567.             if($subject!= null){
  568.                 $pos=$subject->getLabel();
  569.                 return $this->_findInIndex($pos,$subject,$predicate,$object,4);
  570.             }
  571.             if($predicate!= null){
  572.                 $pos=$predicate->getLabel();
  573.                 return $this->_findInIndex($pos,$subject,$predicate,$object,5);
  574.             }
  575.             if($object!= null){
  576.                 $pos=$object->getLabel();
  577.                 return $this->_findInIndex($pos,$subject,$predicate,$object,6);
  578.             }
  579.         }
  580.         // if no index: linear search
  581.         foreach($this->triples as $value{
  582.             if ($this->matchStatement($value$subject$predicate$object))
  583.             $res->add($value);
  584.         }
  585.         return $res;
  586.  
  587.     }
  588.  
  589.  
  590.  
  591.  
  592.  
  593.     /**
  594.     * Method to search for triples using Perl-style regular expressions.
  595.     * NULL input for any parameter will match anything.
  596.     * Example:  $result = $m->find_regex( NULL, NULL, $regex );
  597.     * Finds all triples where the label of the object node matches the regular expression.
  598.     * Returns an empty MemModel if nothing is found.
  599.     *
  600.     * @param    string    $subject_regex 
  601.     * @param    string    $predicate_regex 
  602.     * @param    string    $object_regex 
  603.     * @return    object MemModel 
  604.     * @access    public
  605.     */
  606.     function findRegex($subject_regex$predicate_regex$object_regex{
  607.  
  608.         $res new MemModel($this->getBaseURI());
  609.  
  610.         if($this->size(== 0)
  611.         return $res;
  612.  
  613.         if($subject_regex == NULL && $predicate_regex == NULL && $object_regex == NULL)
  614.         return $this;
  615.  
  616.         foreach($this->triples as $value{
  617.             if (
  618.             ($subject_regex == NULL || preg_match($subject_regex$value->subj->getLabel())) &&
  619.             ($predicate_regex == NULL || preg_match($predicate_regex$value->pred->getLabel())) &&
  620.             ($object_regex == NULL || preg_match($object_regex$value->obj->getLabel()))
  621.             $res->add($value);
  622.         }
  623.  
  624.         return $res;
  625.  
  626.     }
  627.  
  628.     /**
  629.     * Returns all tripels of a certain vocabulary.
  630.     * $vocabulary is the namespace of the vocabulary inluding a # : / char at the end.
  631.     * e.g. http://www.w3.org/2000/01/rdf-schema#
  632.     * Returns an empty MemModel if nothing is found.
  633.     *
  634.     * @param    string    $vocabulary 
  635.     * @return    object MemModel 
  636.     * @access    public
  637.     */
  638.     function findVocabulary($vocabulary{
  639.  
  640.         if($this->size(== 0)
  641.         return new MemModel();
  642.         if($vocabulary == NULL || $vocabulary == '')
  643.         return $this;
  644.  
  645.         $res new MemModel($this->getBaseURI());
  646.         if($this->indexed==0){
  647.             foreach($this->indexArr[5as $key => $value){
  648.                 $pos=strpos($key,'#')+1;
  649.                 if(substr($key,0,$pos)==$vocabulary){
  650.                     for($i=1;$i<=$value[0];$i++){
  651.                         $res->add($this->triples[$value[$i]]);
  652.                     }
  653.                 }
  654.             }
  655.             return $res;
  656.         }else{
  657.             // Import Package Utility
  658.             include_once(RDFAPI_INCLUDE_DIR.PACKAGE_UTILITY);
  659.             foreach($this->triples as $value{
  660.                 if (RDFUtil::getNamespace($value->getPredicate()) == $vocabulary)
  661.                 $res->add($value);
  662.             }
  663.             return $res;
  664.         }
  665.     }
  666.  
  667.     /**
  668.     * Searches for triples and returns the first matching statement.
  669.     * NULL input for any parameter will match anything.
  670.     * Example:  $result = $m->findFirstMatchingStatement( NULL, NULL, $node );
  671.     * Returns the first statement of the MemModel where the object equals $node.
  672.     * Returns an NULL if nothing is found.
  673.     * You can define an offset to search for. Default = 0
  674.     *
  675.     * @param    object Node    $subject 
  676.     * @param    object Node    $predicate 
  677.     * @param    object Node    $object 
  678.     * @param    integer    $offset 
  679.     * @return    object Statement 
  680.     * @access    public
  681.     */
  682.     function findFirstMatchingStatement($subject$predicate$object$offset 0{
  683.  
  684.         $currentOffset 0;
  685.         for($i=0;$i<=$offset;$i++)
  686.         {
  687.             $res $this->findFirstMatchOff($subject$predicate$object$currentOffset);
  688.             $currentOffset=$res+1;
  689.         }
  690.         if ($res != -1{
  691.             return $this->triples[$res];
  692.         else {
  693.             return NULL;
  694.         }
  695.     }
  696.  
  697.  
  698.  
  699.  
  700.     /**
  701.     * Searches for triples and returns the first matching statement from a given offset.
  702.     * This method is used by the util/findIterator. NULL input for any parameter will match anything.
  703.     * Example:  $result = $m->findFirstMatchingStatement( NULL, NULL, $node, $off );
  704.     * Returns the position of the first statement of the MemModel where the object equals $node from the given
  705.     * offset.
  706.     * Returns an -1 if nothing is found.
  707.     *
  708.     * @param    object Node    $subject 
  709.     * @param    object Node    $predicate 
  710.     * @param    object Node    $object 
  711.     * @param int         $off 
  712.     * @return    int 
  713.     * @access    private
  714.     */
  715.     function findFirstMatchOff($subject,$predicate$object,$off{
  716.  
  717.         if (
  718.         (!is_a($subject'Resource'&& $subject != NULL||
  719.         (!is_a($predicate'Resource'&& $predicate != NULL||
  720.         (!is_a($object'Node'&& $object != NULL)
  721.         {
  722.             $errmsg RDFAPI_ERROR '(class: MemModel; method: find): Parameters must be subclasses of Node or NULL';
  723.             trigger_error($errmsgE_USER_ERROR);
  724.         }
  725.  
  726.         $match=-1;
  727.         $ind=$this->indexed;
  728.         if($subject == NULL && $predicate == NULL && $object == NULL)
  729.         {
  730.             foreach ($this->triples as $key => $statement)
  731.             {
  732.                 if ($key >= $off)
  733.                     return $key;
  734.             }
  735.             return -1;
  736.         }
  737.  
  738.         switch($ind){
  739.             case 1:
  740.             if($subject!=NULL && $predicate != NULL && $object != NULL){
  741.                 $pos=$subject->getLabel().$predicate->getLabel().$object->getLabel();
  742.                 return $this->_findMatchIndex($pos,$subject,$predicate,$object,1,$off);
  743.             }else{
  744.                 break;
  745.             }
  746.  
  747.             case 2:
  748.             if($subject!=NULL && $predicate != NULL){
  749.                 $pos=$subject->getLabel().$predicate->getLabel();
  750.                 return $this->_findMatchIndex($pos,$subject,$predicate,$object,2,$off);
  751.             }else{
  752.                 break;
  753.             }
  754.  
  755.             case 3:
  756.             if($subject!=NULL && $object != NULL){
  757.                 $pos=$subject->getLabel().$object->getLabel();
  758.                 return $this->_findMatchIndex($pos,$subject,$predicate,$object,3,$off);
  759.             }else{
  760.                 break;
  761.             }
  762.             case 0:
  763.             if($subject!= null){
  764.                 $pos=$subject->getLabel();
  765.                 return $this->_findMatchIndex($pos,$subject,$predicate,$object,4,$off);
  766.             }
  767.             if($predicate!= null){
  768.                 $pos=$predicate->getLabel();
  769.                 return $this->_findMatchIndex($pos,$subject,$predicate,$object,5,$off);
  770.             }
  771.             if($object!= null){
  772.                 $pos=$object->getLabel();
  773.                 return $this->_findMatchIndex($pos,$subject,$predicate,$object,6,$off);
  774.             }
  775.             break;
  776.         }
  777.         // if no index: linear search
  778.         foreach($this->triples as $key => $value){
  779.             if ($this->matchStatement($value$subject$predicate$object)){
  780.                 if($off<=$key){
  781.                     $match=$key;
  782.                     break;
  783.                 }
  784.             }
  785.         }
  786.         return $match;
  787.     }
  788.  
  789.  
  790.     /**
  791.     * Searches for triples and returns the number of matches.
  792.     * NULL input for any parameter will match anything.
  793.     * Example:  $result = $m->findCount( NULL, NULL, $node );
  794.     * Finds all triples with $node as object.
  795.     *
  796.     * @param    object Node    $subject 
  797.     * @param    object Node    $predicate 
  798.     * @param    object Node    $object 
  799.     * @return    integer 
  800.     * @access    public
  801.     */
  802.     function findCount($subject$predicate$object{
  803.  
  804.         $res $this->find($subject$predicate$object);
  805.         return $res->size();
  806.  
  807.     }
  808.  
  809.  
  810.     /**
  811.     * Perform an RDQL query on this MemModel.
  812.     * This method returns an associative array of variable bindings.
  813.     * The values of the query variables can either be RAP's objects (instances of Node)
  814.     * if $returnNodes set to TRUE, or their string serialization.
  815.     *
  816.     * @access    public
  817.     * @param string $queryString 
  818.     * @param boolean $returnNodes 
  819.     * @return  array   [][?VARNAME] = object Node  (if $returnNodes = TRUE)
  820.     *       OR  array   [][?VARNAME] = string
  821.     *
  822.     */
  823.     function rdqlQuery($queryString$returnNodes TRUE{
  824.  
  825.         // Import RDQL Package
  826.         include_once(RDFAPI_INCLUDE_DIR.PACKAGE_RDQL);
  827.  
  828.         $parser new RdqlParser();
  829.         $parsedQuery =$parser->parseQuery($queryString);
  830.  
  831.         // this method can only query this MemModel
  832.         // if another model was specified in the from clause throw an error
  833.         if (isset($parsedQuery['sources'][1])) {
  834.             $errmsg RDFAPI_ERROR '(class: MemModel; method: rdqlQuery):';
  835.             $errmsg .= ' this method can only query this MemModel';
  836.             trigger_error($errmsgE_USER_ERROR);
  837.         }
  838.  
  839.         $engine new RdqlMemEngine();
  840.         $res =$engine->queryModel($this$parsedQuery$returnNodes);
  841.  
  842.         return $res;
  843.     }
  844.  
  845.     /**
  846.     * Perform an RDQL query on this MemModel.
  847.     * This method returns an RdqlResultIterator of variable bindings.
  848.     * The values of the query variables can either be RAP's objects (instances of Node)
  849.     * if $returnNodes set to TRUE, or their string serialization.
  850.     *
  851.     * @access    public
  852.     * @param string $queryString 
  853.     * @param boolean $returnNodes 
  854.     * @return  object RdqlResultIterator = with values as object Node  (if $returnNodes = TRUE)
  855.     *       OR  object RdqlResultIterator = with values as strings if (if $returnNodes = FALSE)
  856.     *
  857.     */
  858.     function rdqlQueryAsIterator($queryString$returnNodes TRUE{
  859.         // Import RDQL Package
  860.         include_once(RDFAPI_INCLUDE_DIR.PACKAGE_RDQL);
  861.         return new RdqlResultIterator($this->rdqlQuery($queryString$returnNodes));
  862.     }
  863.  
  864.     /**
  865.     * General method to replace nodes of a MemModel.
  866.     * NULL input for any parameter will match nothing.
  867.     * Example:  $m->replace($node, NULL, $node, $replacement);
  868.     * Replaces all $node objects beeing subject or object in
  869.     * any triple of the MemModel with the $needle node.
  870.     *
  871.     * @param    object Node    $subject 
  872.     * @param    object Node    $predicate 
  873.     * @param    object Node    $object 
  874.     * @param    object Node    $replacement 
  875.     * @access    public
  876.     * @throws    PhpError
  877.     */
  878.     function replace($subject$predicate$object$replacement{
  879.  
  880.         if (
  881.         (!is_a($replacement'Node')) ||
  882.         (!is_a($subject'Resource'&& $subject != NULL||
  883.         (!is_a($predicate'Resource'&& $predicate != NULL||
  884.         (!is_a($object'Node'&& $object != NULL)
  885.         {
  886.             $errmsg RDFAPI_ERROR '(class: MemModel; method: replace): Parameters must be subclasses of Node or NULL';
  887.             trigger_error($errmsgE_USER_ERROR);
  888.         }
  889.  
  890.         if($this->size(== 0)
  891.         break;
  892.         foreach($this->triples as $key => $value{
  893.             if ($this->triples[$key]->subj->equals($subject)) {
  894.                 $this->triples[$key]->subj $replacement;
  895.             }
  896.             if ($this->triples[$key]->pred->equals($predicate))
  897.             $this->triples[$key]->pred $replacement;
  898.             if ($this->triples[$key]->obj->equals($object))
  899.             $this->triples[$key]->obj $replacement;
  900.  
  901.         }
  902.         $this->index($this->indexed);
  903.     }
  904.  
  905.  
  906.     /**
  907.     * Internal method that checks, if a statement matches a S, P, O or NULL combination.
  908.     * NULL input for any parameter will match anything.
  909.     *
  910.     * @param    object Statement    $statement 
  911.     * @param    object Node    $subject 
  912.     * @param    object Node    $predicate 
  913.     * @param    object Node    $object 
  914.     * @return    boolean 
  915.     * @access    private
  916.     */
  917.     function matchStatement($statement$subject$predicate$object)  {
  918.  
  919.         if(($subject != NULLAND !($statement->subj->equals($subject)))
  920.         return false;
  921.  
  922.         if($predicate != NULL && !($statement->pred->equals($predicate)))
  923.         return false;
  924.  
  925.         if($object != NULL && !($statement->obj->equals($object)))
  926.         return false;
  927.  
  928.         return true;
  929.     }
  930.  
  931.  
  932.  
  933.  
  934.     /**
  935.     * Checks if two models are equal.
  936.     * Two models are equal if and only if the two RDF graphs they represent are isomorphic.
  937.     *
  938.     * @access    public
  939.     * @param        object    model &$that 
  940.     * @throws    phpErrpr
  941.     * @return    boolean 
  942.     */
  943.  
  944.     function equals(&$that)  {
  945.  
  946.         if (!is_a($that'Model')) {
  947.             $errmsg RDFAPI_ERROR '(class: MemModel; method: equals): Model expected.';
  948.             trigger_error($errmsgE_USER_ERROR);
  949.         }
  950.  
  951.         if ($this->size(!= $that->size())
  952.         return FALSE;
  953.         /*
  954.         if (!$this->containsAll($that))
  955.         return FALSE;
  956.         return TRUE;
  957.         */
  958.         include_once(RDFAPI_INCLUDE_DIR"util/ModelComparator.php");
  959.         return ModelComparator::compare($this,$that);
  960.     }
  961.  
  962.     /**
  963.     * Returns a new MemModel that is the set-union of the MemModel with another model.
  964.     * Duplicate statements are removed. If you want to allow duplicates, use addModel() which is much faster.
  965.     *
  966.     * The result of taking the set-union of two or more RDF graphs (i.e. sets of triples)
  967.     * is another graph, which we will call the merge of the graphs.
  968.     * Each of the original graphs is a subgraph of the merged graph. Notice that when forming
  969.     * a merged graph, two occurrences of a given uriref or literal as nodes in two different
  970.     * graphs become a single node in the union graph (since by definition they are the same
  971.     * uriref or literal) but blank nodes are not 'merged' in this way; and arcs are of course
  972.     * never merged. In particular, this means that every blank node in a merged graph can be
  973.     * identified as coming from one particular graph in the original set of graphs.
  974.     *
  975.     * Notice that one does not, in general, obtain the merge of a set of graphs by concatenating
  976.     * their corresponding N-triples documents and constructing the graph described by the merged
  977.     * document, since if some of the documents use the same node identifiers, the merged document
  978.     * will describe a graph in which some of the blank nodes have been 'accidentally' merged.
  979.     * To merge Ntriples documents it is necessary to check if the same nodeID is used in two or
  980.     * more documents, and to replace it with a distinct nodeID in each of them, before merging the
  981.     * documents. (Not implemented yet !!!!!!!!!!!)
  982.     *
  983.     * @param    object Model    $model 
  984.     * @return    object MemModel 
  985.     * @access    public
  986.     * @throws phpErrpr
  987.     *
  988.     */
  989.     function unite(&$model)  {
  990.  
  991.         if (!is_a($model'Model')) {
  992.             $errmsg RDFAPI_ERROR '(class: MemModel; method: unite): Model expected.';
  993.             trigger_error($errmsgE_USER_ERROR);
  994.         }
  995.  
  996.         $res $this;
  997.  
  998.         if (is_a($model'MemModel')) {
  999.             require_once RDFAPI_INCLUDE_DIR 'util/StatementIterator.php';
  1000.             $stateIt=new StatementIterator($model);
  1001.             while($statement=$stateIt->next())
  1002.             {
  1003.                 $res->addWithoutDuplicates($statement);
  1004.             }
  1005.         }
  1006.  
  1007.         elseif (is_a($model'DbModel')) {
  1008.             $memModel =$model->getMemModel();
  1009.             foreach($memModel->triples as $value)
  1010.             $res->addWithoutDuplicates($value);
  1011.         }
  1012.  
  1013.         return $res;
  1014.     }
  1015.  
  1016.     /**
  1017.     * Returns a new MemModel that is the subtraction of another model from this MemModel.
  1018.     *
  1019.     * @param    object Model    $model 
  1020.     * @return    object MemModel 
  1021.     * @access    public
  1022.     * @throws phpErrpr
  1023.     */
  1024.  
  1025.     function subtract(&$model)  {
  1026.  
  1027.         if (!is_a($model'Model')) {
  1028.             $errmsg RDFAPI_ERROR '(class: MemModel; method: subtract): Model expected.';
  1029.             trigger_error($errmsgE_USER_ERROR);
  1030.         }
  1031.  
  1032.         $res $this;
  1033.  
  1034.  
  1035.         if (is_a($model'MemModel'))
  1036.         {
  1037.             require_once RDFAPI_INCLUDE_DIR 'util/StatementIterator.php';
  1038.             $stateIt=new StatementIterator($model);
  1039.             while($statement=$stateIt->next())
  1040.             {
  1041.                 $res->remove($statement);
  1042.             }
  1043.         }
  1044.         elseif (is_a($model'DbModel'))
  1045.         {
  1046.             $memModel =$model->getMemModel();
  1047.             foreach($memModel->triples as $value)
  1048.             $res->remove($value);
  1049.         }
  1050.  
  1051.  
  1052.         return $res;
  1053.     }
  1054.  
  1055.     /**
  1056.     * Returns a new MemModel containing all the statements which are in both this MemModel and another.
  1057.     *
  1058.     * @param    object Model    $model 
  1059.     * @return    object MemModel 
  1060.     * @access    public
  1061.     * @throws phpErrpr
  1062.     */
  1063.     function intersect(&$model)  {
  1064.  
  1065.         if (!is_a($model'Model')) {
  1066.             $errmsg RDFAPI_ERROR '(class: MemModel; method: intersect: Model expected.';
  1067.             trigger_error($errmsgE_USER_ERROR);
  1068.         }
  1069.  
  1070.         $res new MemModel($this->getBaseURI());
  1071.  
  1072.         if (is_a($model'DbModel'|| is_a($model'RDFSBModel'))
  1073.         {
  1074.             $memModel =$model->getMemModel();
  1075.             foreach($memModel->triples as $value{
  1076.                 if ($this->contains($value))
  1077.                 $res->add($value);
  1078.             }
  1079.         }
  1080.  
  1081.         elseif (is_a($model'MemModel'))
  1082.         {
  1083.             foreach($model->triples as $value{
  1084.                 if ($this->contains($value))
  1085.                 $res->add($value);
  1086.             }
  1087.         }
  1088.  
  1089.  
  1090.  
  1091.         return $res;
  1092.     }
  1093.  
  1094.  
  1095.     /**
  1096.     * Adds another model to this MemModel.
  1097.     * Duplicate statements are not removed.
  1098.     * If you don't want duplicates, use unite().
  1099.     * If any statement of the model to be added to this model contains a blankNode
  1100.     * with an identifier already existing in this model, a new blankNode is generated.
  1101.     *
  1102.     * @param    object Model    $model 
  1103.     * @access    public
  1104.     * @throws phpErrpr
  1105.     *
  1106.     */
  1107.     function addModel(&$model)  {
  1108.  
  1109.         if (!is_a($model'Model')) {
  1110.             $errmsg RDFAPI_ERROR '(class: MemModel; method: addModel): Model expected.';
  1111.             trigger_error($errmsgE_USER_ERROR);
  1112.         }
  1113.  
  1114.         $blankNodes_tmp array();
  1115.  
  1116.         if (is_a($model'MemModel')) {
  1117.             require_once RDFAPI_INCLUDE_DIR 'util/StatementIterator.php';
  1118.             $stateIt=new StatementIterator($model);
  1119.             while($statement=$stateIt->next())
  1120.             {
  1121.                 $this->_addStatementFromAnotherModel($statement$blankNodes_tmp);
  1122.             };
  1123.             $this->addParsedNamespaces($model->getParsedNamespaces());
  1124.         }
  1125.  
  1126.         elseif (is_a($model'DbModel')) {
  1127.             $memModel =$model->getMemModel();
  1128.             foreach($memModel->triples as $value)
  1129.             $this->_addStatementFromAnotherModel($value$blankNodes_tmp);
  1130.         }
  1131.         $this->index($this->indexed);
  1132.     }
  1133.  
  1134.  
  1135.     /**
  1136.     * Reifies the MemModel.
  1137.     * Returns a new MemModel that contains the reifications of all statements of this MemModel.
  1138.     *
  1139.     * @access    public
  1140.     * @return    object    MemModel 
  1141.     */
  1142.     function reify({
  1143.         $res new MemModel($this->getBaseURI());
  1144.  
  1145.         $stateIt=$this->getStatementIterator();
  1146.         while($statement=$stateIt->next())
  1147.         {
  1148.             $pointer =$statement->reify($res);
  1149.             $res->addModel($pointer);
  1150.         };
  1151.  
  1152.         return $res;
  1153.     }
  1154.  
  1155.     /**
  1156.     * Returns a StatementIterator for traversing the MemModel.
  1157.     * @access    public
  1158.     * @return    object    StatementIterator 
  1159.     */
  1160.     function getStatementIterator({
  1161.         // Import Package Utility
  1162.         require_once RDFAPI_INCLUDE_DIR 'util/StatementIterator.php';
  1163.  
  1164.         $si new StatementIterator($this);
  1165.         return $si;
  1166.     }
  1167.  
  1168.     /**
  1169.     * Returns a FindIterator for traversing the MemModel.
  1170.     * @access    public
  1171.     * @return    object    FindIterator 
  1172.     */
  1173.     function findAsIterator($sub=null,$pred=null,$obj=null{
  1174.         // Import Package Utility
  1175.         require_once RDFAPI_INCLUDE_DIR 'util/FindIterator.php';
  1176.  
  1177.         $if new FindIterator($this,$sub,$pred,$obj);
  1178.         return $if;
  1179.     }
  1180.  
  1181.     /**
  1182.     * Returns a FindIterator for traversing the MemModel.
  1183.     * @access    public
  1184.     * @return    object    FindIterator 
  1185.     */
  1186.     function iterFind($sub=null,$pred=null,$obj=null{
  1187.         // Import Package Utility
  1188.         require_once RDFAPI_INCLUDE_DIR 'util/IterFind.php';
  1189.  
  1190.         $if new IterFind($this,$sub,$pred,$obj);
  1191.         return $if;
  1192.     }
  1193.  
  1194.  
  1195.     /**
  1196.     * Returns the models namespaces.
  1197.     *
  1198.     * @author   Tobias Gau�<tobias.gauss@web.de>
  1199.     * @access   public
  1200.     * @return   Array 
  1201.     */
  1202.     function getParsedNamespaces(){
  1203.         if(count($this->parsedNamespaces)!=0){
  1204.             return $this->parsedNamespaces;
  1205.         }else{
  1206.             return false;
  1207.         }
  1208.     }
  1209.  
  1210.  
  1211.  
  1212.     /**
  1213.     * Adds the namespaces to the model. This method is called by
  1214.     * the parser. !!!! addParsedNamespaces() not overwrites manual
  1215.     * added namespaces in the model !!!!
  1216.     *
  1217.     * @author   Tobias Gau�<tobias.gauss@web.de>
  1218.     * @access   public
  1219.     * @param    Array $newNs 
  1220.     */
  1221.     function addParsedNamespaces($newNs){
  1222.         if($newNs)
  1223.         $this->parsedNamespaces $this->parsedNamespaces $newNs;
  1224.     }
  1225.  
  1226.  
  1227.     /**
  1228.     * Adds a namespace and prefix to the model.
  1229.     *
  1230.     * @author   Tobias Gau�<tobias.gauss@web.de>
  1231.     * @access   public
  1232.     * @param    String 
  1233.     * @param    String 
  1234.     */
  1235.     function addNamespace($prefix$nmsp){
  1236.         $this->parsedNamespaces[$nmsp]=$prefix;
  1237.     }
  1238.  
  1239.     /**
  1240.     * removes a single namespace from the model
  1241.     *
  1242.     * @author   Tobias Gau�<tobias.gauss@web.de>
  1243.     * @access   public
  1244.     * @param    String $nmsp 
  1245.     */
  1246.     function removeNamespace($nmsp){
  1247.         if(isset($this->parsedNamespaces[$nmsp])){
  1248.             unset($this->parsedNamespaces[$nmsp]);
  1249.             return true;
  1250.         }else{
  1251.             return false;
  1252.         }
  1253.     }
  1254.  
  1255.  
  1256.  
  1257.     /**
  1258.     * Close the MemModel and free up resources held.
  1259.     *
  1260.     * @access    public
  1261.     */
  1262.     function close({
  1263.         unset$this->baseURI );
  1264.         unset$this->triples );
  1265.     }
  1266.  
  1267.     // =============================================================================
  1268.     // *************************** helper functions ********************************
  1269.     // =============================================================================
  1270.     /**
  1271.     * Checks if $statement is in index
  1272.     *
  1273.     * @param  int $ind 
  1274.     * @param  Statement &$statement 
  1275.     * @return boolean 
  1276.     * @access private
  1277.     */
  1278.     function _containsIndex(&$statement,$ind){
  1279.         switch($ind){
  1280.             case 4:
  1281.             $sub=$statement->getSubject();
  1282.             $pos=$sub->getLabel();
  1283.             break;
  1284.             case 1:
  1285.             $sub=$statement->getSubject();
  1286.             $pred=$statement->getPredicate();
  1287.             $obj=$statement->getObject();
  1288.             $pos=$sub->getLabel().$pred->getLabel().$obj->getLabel();
  1289.             break;
  1290.             case 2:
  1291.             $sub=$statement->getSubject();
  1292.             $pred=$statement->getPredicate();
  1293.             $pos=$sub->getLabel().$pred->getLabel();
  1294.             break;
  1295.             case 3:
  1296.             $sub=$statement->getSubject();
  1297.             $obj=$statement->getObject();
  1298.             $pos=$sub->getLabel().$obj->getLabel();
  1299.             break;
  1300.         }
  1301.  
  1302.         if (!isset($this->indexArr[$ind][$pos]))
  1303.         return FALSE;
  1304.         foreach ($this->indexArr[$ind][$posas $key => $value{
  1305.             $t=$this->triples[$value];
  1306.             if ($t->equals($statement))
  1307.             return TRUE;
  1308.         }
  1309.         return FALSE;
  1310.     }
  1311.  
  1312.  
  1313.  
  1314.  
  1315.  
  1316.     /**
  1317.     * finds a statement in an index. $pos is the Position in the index
  1318.     * and $ind the adequate searchindex
  1319.     *
  1320.     * @param    String            $pos 
  1321.     * @param    Object Subject    &$subject
  1322.     * @param    Object Predicate  &$predicate
  1323.     * @param    Object Object     &$object
  1324.     * @param    int                 &ind
  1325.     * @return   MemModel          $res
  1326.     * @access   private
  1327.     */
  1328.     function _findInIndex($pos,&$subject,&$predicate,&$object,$ind){
  1329.         $res new MemModel($this->getBaseURI());
  1330.         $res->indexed=-1;
  1331.         if (!isset($this->indexArr[$ind][$pos]))
  1332.         return $res;
  1333.         foreach($this->indexArr[$ind][$posas $key =>$value){
  1334.             $t=$this->triples[$value];
  1335.             if ($this->matchStatement($t,$subject,$predicate,$object))
  1336.             $res->add($t);
  1337.         }
  1338.         return $res;
  1339.     }
  1340.     /**
  1341.     * adds/removes a statement into/from an index.
  1342.     * mode=0 removes the statement from the index;
  1343.     * mode=1 adds the statement into the index.
  1344.     * returns the statements position.
  1345.     *
  1346.     * @param Object Statement &$statement
  1347.     *    @param int              $k 
  1348.     *    @param int              $ind 
  1349.     * @param int                $mode 
  1350.     * @return int             $k
  1351.     * @access private
  1352.     */
  1353.     function _indexOpr(&$statement,$k,$ind,$mode){
  1354.         // determine position in adequate index
  1355.         switch($ind){
  1356.             case 1:
  1357.             $s=$statement->getSubject();
  1358.             $p=$statement->getPredicate();
  1359.             $o=$statement->getObject();
  1360.             $pos=$s->getLabel().$p->getLabel().$o->getLabel();
  1361.             break;
  1362.             case 2:
  1363.             $s=$statement->getSubject();
  1364.             $p=$statement->getPredicate();
  1365.             $pos=$s->getLabel().$p->getLabel();
  1366.             break;
  1367.             case 3:
  1368.             $s=$statement->getSubject();
  1369.             $o=$statement->getObject();
  1370.             $pos=$s->getLabel().$o->getLabel();
  1371.             break;
  1372.             case 4:
  1373.             $s=$statement->getSubject();
  1374.             $pos=$s->getLabel();
  1375.             break;
  1376.             case 5:
  1377.             $p=$statement->getPredicate();
  1378.             $pos=$p->getLabel();
  1379.             break;
  1380.             case 6:
  1381.             $o=$statement->getObject();
  1382.             $pos=$o->getLabel();
  1383.             break;
  1384.         }
  1385.         switch($mode){
  1386.             // add in Index
  1387.             case 1:
  1388.             if(isset($this->indexArr[$ind][$pos])){
  1389.                 $this->indexArr[$ind][$pos][$k;
  1390.             }else{
  1391.                 $this->indexArr[$ind][$pos][0$k;
  1392.             }
  1393.             break;
  1394.             // remove from Index
  1395.             case 0:
  1396.             $subject=$statement->getSubject();
  1397.             $predicate=$statement->getPredicate();
  1398.             $object=$statement->getObject();
  1399.             $k=-1;
  1400.             if(!isset($this->indexArr[$ind][$pos])){
  1401.                 return -1;
  1402.             }
  1403.             $num=count($this->indexArr[$ind][$pos]);
  1404.             foreach($this->indexArr[$ind][$posas $key => $value){
  1405.                 $t=$this->triples[$value];
  1406.                 if($this->matchStatement($t,$subject,$predicate,$object)){
  1407.                     $k=$value;
  1408.                     if($num==1){
  1409.                         unset($this->indexArr[$ind][$pos]);
  1410.                     }else{
  1411.                         unset($this->indexArr[$ind][$pos][$key]);
  1412.                     }
  1413.                     return $k;
  1414.                 }
  1415.             }
  1416.             break;
  1417.         }
  1418.         return $k;
  1419.     }
  1420.  
  1421.  
  1422.     /**
  1423.     * finds next or previous matching statement.
  1424.     * Returns Position in model or -1 if there is no match.
  1425.     *
  1426.     *
  1427.     * @param        String 
  1428.     * @param     object  Subject 
  1429.     * @param        object    Predicate 
  1430.     * @param     object  Object 
  1431.     * @param     integer 
  1432.     * @param     integer 
  1433.     * @return    integer 
  1434.     * @access    private
  1435.     */
  1436.     function _findMatchIndex($pos,&$s,&$p,&$o,$ind,$off){
  1437.         $match=-1;
  1438.         if (!isset($this->indexArr[$ind][$pos])) {
  1439.             return $match;}
  1440.             foreach($this->indexArr[$ind][$posas $key =>$value){
  1441.                 $t=$this->triples[$value];
  1442.                 if ($this->matchStatement($t,$s,$p,$o)){
  1443.                     if($off <= $value){
  1444.                         $match$value;
  1445.                         return $match;
  1446.                     }
  1447.                 }
  1448.             }
  1449.  
  1450.             return $match;
  1451.  
  1452.     }
  1453.  
  1454.  
  1455.  
  1456.  
  1457. // end: MemModel
  1458.  
  1459.  
  1460. ?>

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