import java.io.PrintWriter;
import java.util.Iterator;

import org.apache.jena.ontology.OntModel;
import org.apache.jena.ontology.OntModelSpec;
import org.apache.jena.rdf.model.Model;
import org.apache.jena.rdf.model.ModelFactory;
import org.apache.jena.rdf.model.RDFNode;
import org.apache.jena.rdf.model.Statement;
import org.apache.jena.rdf.model.StmtIterator;
import org.apache.jena.reasoner.Derivation;
import org.apache.jena.reasoner.Reasoner;
import org.apache.jena.util.FileManager;

public class JenaIntRuleDeductions {
  static String filepath = "/home/may/teaching/SemWeb/RDF/";
  public static void main(String[] args){
    Model m = FileManager.get().loadModel(filepath + "descendants.n3");
    OntModel ontmodel = ModelFactory.createOntologyModel(OntModelSpec.OWL_DL_MEM_RULE_INF, m);
    Reasoner reasoner = ontmodel.getReasoner();
    reasoner.setDerivationLogging(true);

    Model dedModel = ontmodel.getDeductionsModel();
    if (dedModel == null) System.out.println("DedModel is null");  // it is null ...
        else dedModel.write(System.out,"N3");   // viele triviale OWL-Axiome im DedModel
    Model rawModel = ontmodel.getRawModel();
    Model diffModel = ontmodel.difference(rawModel).difference(dedModel);
    System.out.println("---- DiffModel: ----------------------");
    diffModel.write(System.out,"N3");  // vieles, incl die sinnvollen Ergebnisse im DiffModel

    PrintWriter out = new PrintWriter(System.out);
    for (StmtIterator i = diffModel.listStatements(null,
        ontmodel.getProperty("foo://bla/meta#descendant"),
        (RDFNode) null); i.hasNext(); ) {
        Statement s = i.nextStatement();
        out.write("Statement is " + s + "\n");
        Iterator <Derivation> ds = ontmodel.getDerivation(s);
        if (ds == null) System.out.println("DerivationsIterator is null");
        else for (Iterator<Derivation> i2 = ontmodel.getDerivation(s); i2.hasNext(); ) {
            Derivation deriv = (Derivation) i2.next();
            deriv.printTrace(out, true);   // derivations are not null, but empty
    }   }
    out.flush();
}}
