Source for file InfModelF.php

Documentation is available at InfModelF.php

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

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