source: Dev/trunk/rdfapi/infModel/InfModelF.php @ 12

Last change on this file since 12 was 12, checked in by basvannuland, 14 years ago

Added RAP RDF API
Added RDF reader writer for save and load survey

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