Source for file InfModelF.php

Documentation is available at InfModelF.php

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

Documentation generated on Fri, 17 Dec 2004 16:15:20 +0100 by phpDocumentor 1.3.0RC3