On Mon, Aug 12, 2013 at 4:19 PM, Joshua TAYLOR <[email protected]> wrote: > On Mon, Aug 12, 2013 at 4:11 PM, Joshua TAYLOR <[email protected]> wrote: >> On Mon, Aug 12, 2013 at 3:23 PM, Niranjan Balasubramanian >> <[email protected]> wrote: >>> Yes, getting at *all* possible derivations is bound to be problematic. How >>> about finding K traces through the derivation graph? Is there any way to >>> force the backward-chaining procedure to run until the answer is found K >>> times (via different paths) or until the search space is exhausted? >> >> Depending on your ruleset and how much of the derivation you need, you >> can do a lot with print statements in your rules. For instance >> >> @prefix ex: <http://example.org/> . >> >> [(ex:A ex:B ex:C) <- >> print( derivation 1 )] >> [(ex:A ex:B ex:C) <- >> print( derivation 2 )] >> [(ex:A ex:B ex:C) <- >> print( derivation 3 )] >> >> contains three rules that will produce (A B C). When writing out an >> inference model based on these rules, all three rules are fired, even >> though the model only contains one statement (A B C). For instance, >> here's code that iterates through the statements of an inference model >> based on these rules: >> >> import java.io.BufferedReader; >> import java.io.ByteArrayInputStream; >> import java.io.IOException; >> import java.io.InputStream; >> import java.io.InputStreamReader; >> >> import com.hp.hpl.jena.rdf.model.InfModel; >> import com.hp.hpl.jena.rdf.model.Model; >> import com.hp.hpl.jena.rdf.model.ModelFactory; >> import com.hp.hpl.jena.rdf.model.StmtIterator; >> import com.hp.hpl.jena.reasoner.Reasoner; >> import com.hp.hpl.jena.reasoner.rulesys.GenericRuleReasoner; >> import com.hp.hpl.jena.reasoner.rulesys.Rule; >> >> >> public class DerivationsFinder { >> final static String ruleText = "" + >> "@prefix ex: <http://example.org/> .\n" + >> "\n" + >> "[(ex:A ex:B ex:C) <-\n" + >> " print( derivation 1 )]\n" + >> "[(ex:A ex:B ex:C) <-\n" + >> " print( derivation 2 )]\n" + >> "[(ex:A ex:B ex:C) <-\n" + >> " print( derivation 3 )]\n" + >> ""; >> >> public static void main(String[] args) throws IOException { >> try ( final InputStream in = new ByteArrayInputStream( >> ruleText.getBytes() ); >> final InputStreamReader reader = new >> InputStreamReader( in ); >> final BufferedReader buff = new BufferedReader( >> reader ) ) { >> >> final Reasoner reasoner = new GenericRuleReasoner( >> Rule.parseRules( >> Rule.rulesParserFromReader( buff ))); >> final Model model = >> ModelFactory.createDefaultModel(); >> final InfModel infModel = >> ModelFactory.createInfModel( reasoner, model ); >> >> for ( final StmtIterator it = >> infModel.listStatements(); it.hasNext(); ) { >> System.out.println( it.next() ); >> } >> } >> } >> } >> >> The output is: >> >> derivation '1'^^http://www.w3.org/2001/XMLSchema#int >> [http://example.org/A, http://example.org/B, http://example.org/C] >> derivation '2'^^http://www.w3.org/2001/XMLSchema#int >> derivation '3'^^http://www.w3.org/2001/XMLSchema#int >> >> If you can put enough debugging output in your rules, you should be >> able to capture a bunch of the derivations. > > Hm. Trying out something like this on the rules that you provided > doesn't seem to work for me, actually. Sorry. I'll take a bit more of > a look, but I guess this isn't a great approach after all.
Sorry for so much replying to my own noise, but I'm twice mistaken now. The problem with the original ruleset is that Jena rules don't support the abbreviation 'a' for `rdf:type` and I'd naïvely copied the data into the rules. If you have a ruleset like @prefix : http://myexample.org/ [rule1: (?a :conductorOf :electricity) <- (?a rdf:type :Metal) print( rule1 ?a )] [rule2: (?x :conductorOf ?z) <- (?x :conducts ?z) print( rule2 ?x ?z )] (:iron rdf:type :Metal) <- . (:iron :conducts :electricity) <- . and you create an infModel based on it, and iterate through the statements in the model, both rules will get triggered, as seen in the output: [http://myexample.org/iron, http://www.w3.org/1999/02/22-rdf-syntax-ns#type, http://myexample.org/Metal] [http://myexample.org/iron, http://myexample.org/conducts, http://myexample.org/electricity] rule1 http://myexample.org/iron [http://myexample.org/iron, http://myexample.org/conductorOf, http://myexample.org/electricity] rule2 http://myexample.org/iron http://myexample.org/electricity which has three (as expected) triples, and two lines generated by the print statements. The output from print, since it's the last term in the rule, means that the rule has fired successfully and derived the appropriate triple. Here's code to reproduce: import java.io.BufferedReader; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import com.hp.hpl.jena.rdf.model.InfModel; import com.hp.hpl.jena.rdf.model.Model; import com.hp.hpl.jena.rdf.model.ModelFactory; import com.hp.hpl.jena.rdf.model.StmtIterator; import com.hp.hpl.jena.reasoner.Reasoner; import com.hp.hpl.jena.reasoner.rulesys.GenericRuleReasoner; import com.hp.hpl.jena.reasoner.rulesys.Rule; public class DerivationsFinder { final static String conductorRules = ""+ "@prefix : http://myexample.org/\n" + "[rule1: (?a :conductorOf :electricity) <- (?a rdf:type :Metal) print( rule1 ?a )]\n" + "[rule2: (?x :conductorOf ?z) <- (?x :conducts ?z) print( rule2 ?x ?z )]\n" + "(:iron rdf:type :Metal) <- .\n" + "(:iron :conducts :electricity) <- .\n" + ""; public static void main(String[] args) throws IOException { try ( final InputStream in = new ByteArrayInputStream( conductorRules.getBytes() ); final InputStreamReader reader = new InputStreamReader( in ); final BufferedReader buff = new BufferedReader( reader ) ) { final Reasoner reasoner = new GenericRuleReasoner( Rule.parseRules( Rule.rulesParserFromReader( buff ))); final Model model = ModelFactory.createDefaultModel(); final InfModel infModel = ModelFactory.createInfModel( reasoner, model ); for ( final StmtIterator it = infModel.listStatements(); it.hasNext(); ) { System.out.println( it.next() ); } } } } -- Joshua Taylor, http://www.cs.rpi.edu/~tayloj/
