Source for file MemModel.php

Documentation is available at MemModel.php

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

Documentation generated on Mon, 26 Jun 2006 14:25:37 +0200 by phpDocumentor 1.3.0RC6