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

Documentation generated on Fri, 13 Jan 2006 07:48:34 +0100 by phpDocumentor 1.3.0RC4