Source for file MemModel.php

Documentation is available at MemModel.php

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

Documentation generated on Thu, 7 Jul 2005 13:42:00 +0200 by phpDocumentor 1.3.0RC3