001: /******************************************************************
002: * File: RuleMap.java
003: * Created by: Dave Reynolds
004: * Created on: 04-Mar-2004
005: *
006: * (c) Copyright 2004, 2005, 2006, 2007, 2008 Hewlett-Packard Development Company, LP, all rights reserved.
007: * [See end of file]
008: * $Id: RuleMap.java,v 1.14 2008/01/02 12:08:16 andy_seaborne Exp $
009: *****************************************************************/package jena;
010:
011: import com.hp.hpl.jena.graph.*;
012: import com.hp.hpl.jena.rdf.model.*;
013: import com.hp.hpl.jena.reasoner.Reasoner;
014: import com.hp.hpl.jena.reasoner.rulesys.*;
015: import com.hp.hpl.jena.reasoner.rulesys.builtins.BaseBuiltin;
016: import com.hp.hpl.jena.util.FileManager;
017: import com.hp.hpl.jena.util.FileUtils;
018:
019: import jena.cmdline.*;
020: import java.util.*;
021: import java.io.*;
022:
023: /**
024: * General command line utility to process one RDF file into another
025: * by application of a set of forward chaining rules.
026: * <pre>
027: * Usage: RuleMap [-il inlang] [-ol outlang] [-d] rulefile infile
028: * </pre>
029: * The resulting RDF data is written to stdout in format <code>outlang</code>
030: * (default N3). If <code>-d</code> is given then only the deductions
031: * generated by the rules are output. Otherwise all data including any input
032: * data (other than any removed triples) is output.
033: * <p>
034: * Rules are permitted an additional action "deduce" which forces triples
035: * to be added to the deductions graph even if they are already known (for use
036: * in deductions only mode).
037: * </p>
038: *
039: * @author <a href="mailto:der@hplb.hpl.hp.com">Dave Reynolds</a>
040: * @version $Revision: 1.14 $ on $Date: 2008/01/02 12:08:16 $
041: */
042: public class RuleMap {
043:
044: /**
045: * Load a set of rule definitions including processing of
046: * comment lines and any initial prefix definition lines.
047: * Also notes the prefix definitions for adding to a later inf model.
048: */
049: public static List loadRules(String filename, Map prefixes)
050: throws IOException {
051: String fname = filename;
052: if (fname.startsWith("file:///")) {
053: fname = File.separator + fname.substring(8);
054: } else if (fname.startsWith("file:/")) {
055: fname = File.separator + fname.substring(6);
056: } else if (fname.startsWith("file:")) {
057: fname = fname.substring(5);
058: }
059:
060: BufferedReader src = FileUtils.openResourceFile(fname);
061: return loadRules(src, prefixes);
062: }
063:
064: /**
065: * Load a set of rule definitions including processing of
066: * comment lines and any initial prefix definition lines.
067: * Also notes the prefix definitions for adding to a later inf model.
068: */
069: public static List loadRules(BufferedReader src, Map prefixes)
070: throws IOException {
071: Rule.Parser parser = Rule.rulesParserFromReader(src);
072: List rules = Rule.parseRules(parser);
073: prefixes.putAll(parser.getPrefixMap());
074: return rules;
075: }
076:
077: /**
078: * Internal implementation of the "deduce" primitve.
079: * This takes the form <code> ... -> deduce(s, p, o)</code>
080: */
081: static class Deduce extends BaseBuiltin {
082:
083: /**
084: * Return a name for this builtin, normally this will be the name of the
085: * functor that will be used to invoke it.
086: */
087: public String getName() {
088: return "deduce";
089: }
090:
091: /**
092: * Return the expected number of arguments for this functor or 0 if the number is flexible.
093: */
094: public int getArgLength() {
095: return 3;
096: }
097:
098: /**
099: * This method is invoked when the builtin is called in a rule head.
100: * Such a use is only valid in a forward rule.
101: * @param args the array of argument values for the builtin, this is an array
102: * of Nodes.
103: * @param length the length of the argument list, may be less than the length of the args array
104: * for some rule engines
105: * @param context an execution context giving access to other relevant data
106: */
107: public void headAction(Node[] args, int length,
108: RuleContext context) {
109: if (context.getGraph() instanceof FBRuleInfGraph) {
110: Triple t = new Triple(args[0], args[1], args[2]);
111: ((FBRuleInfGraph) context.getGraph()).addDeduction(t);
112: } else {
113: throw new BuiltinException(this , context,
114: "Only usable in FBrule graphs");
115: }
116: }
117: }
118:
119: /**
120: * General command line utility to process one RDF file into another
121: * by application of a set of forward chaining rules.
122: * <pre>
123: * Usage: RuleMap [-il inlang] [-ol outlang] -d infile rulefile
124: * </pre>
125: */
126: public static void main(String[] args) {
127: try {
128:
129: // Parse the command line
130: CommandLine cl = new CommandLine();
131: String usage = "Usage: RuleMap [-il inlang] [-ol outlang] [-d] rulefile infile (- for stdin)";
132: cl.setUsage(usage);
133: cl.add("il", true);
134: cl.add("ol", true);
135: cl.add("d", false);
136: cl.process(args);
137: if (cl.numItems() != 2) {
138: System.err.println(usage);
139: System.exit(1);
140: }
141:
142: // Load the input data
143: Arg il = cl.getArg("il");
144: String inLang = (il == null) ? null : il.getValue();
145: String fname = cl.getItem(1);
146: Model inModel = null;
147: if (fname.equals("-")) {
148: inModel = ModelFactory.createDefaultModel();
149: inModel.read(System.in, null, inLang);
150: } else {
151: inModel = FileManager.get().loadModel(fname, inLang);
152: }
153:
154: // Determine the type of the output
155: Arg ol = cl.getArg("ol");
156: String outLang = (ol == null) ? "N3" : ol.getValue();
157:
158: Arg d = cl.getArg("d");
159: boolean deductionsOnly = (d != null);
160:
161: // Fetch the rule set and create the reasoner
162: BuiltinRegistry.theRegistry.register(new Deduce());
163: Map prefixes = new HashMap();
164: List rules = loadRules((String) cl.getItem(0), prefixes);
165: Reasoner reasoner = new GenericRuleReasoner(rules);
166:
167: // Process
168: InfModel infModel = ModelFactory.createInfModel(reasoner,
169: inModel);
170: infModel.prepare();
171: infModel.setNsPrefixes(prefixes);
172:
173: // Output
174: PrintWriter writer = new PrintWriter(System.out);
175: if (deductionsOnly) {
176: Model deductions = infModel.getDeductionsModel();
177: deductions.setNsPrefixes(prefixes);
178: deductions.setNsPrefixes(inModel);
179: deductions.write(writer, outLang);
180: } else {
181: infModel.write(writer, outLang);
182: }
183: writer.close();
184:
185: } catch (Throwable t) {
186: System.err.println("An error occured: \n" + t);
187: t.printStackTrace();
188: }
189: }
190:
191: }
192:
193: /*
194: (c) Copyright 2004, 2005, 2006, 2007, 2008 Hewlett-Packard Development Company, LP
195: All rights reserved.
196:
197: Redistribution and use in source and binary forms, with or without
198: modification, are permitted provided that the following conditions
199: are met:
200:
201: 1. Redistributions of source code must retain the above copyright
202: notice, this list of conditions and the following disclaimer.
203:
204: 2. Redistributions in binary form must reproduce the above copyright
205: notice, this list of conditions and the following disclaimer in the
206: documentation and/or other materials provided with the distribution.
207:
208: 3. The name of the author may not be used to endorse or promote products
209: derived from this software without specific prior written permission.
210:
211: THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
212: IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
213: OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
214: IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
215: INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
216: NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
217: DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
218: THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
219: (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
220: THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
221: */
|