import java.io.PrintWriter;
import java.util.Iterator;
import java.util.List;
import org.apache.jena.query.Query;
import org.apache.jena.query.QueryExecution;
import org.apache.jena.query.QueryExecutionFactory;
import org.apache.jena.query.QueryFactory;
import org.apache.jena.query.ResultSet;
import org.apache.jena.query.ResultSetFormatter;
import org.apache.jena.rdf.model.InfModel;
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.rulesys.GenericRuleReasoner;
import org.apache.jena.reasoner.rulesys.Rule;
import org.apache.jena.util.FileManager;

public class JenaRulesBwdDedModel {
  static String filepath = "/home/may/teaching/SemWeb/RDF/";
  public static void main(String[] args){
    // Model model = ModelFactory.createDefaultModel();
    Model m = FileManager.get().loadModel(filepath + "mondial-europe.n3");
    List<Rule> rules = Rule.rulesFromURL(filepath + "rule-neighbor-bigcountries.rl");
    GenericRuleReasoner reasoner = new GenericRuleReasoner(rules);
    reasoner.setMode(GenericRuleReasoner.HYBRID);
    reasoner.setDerivationLogging(true);
    InfModel model = ModelFactory.createInfModel(reasoner, m);
    String q = "prefix mon: <http://www.semwebtech.org/mondial/10/meta#>" +
             "select ?N ?X" +
               " where {{ <http://www.semwebtech.org/mondial/10/countries/D/>" +
             "          mon:bigneighborwith ?X }" +
             "  union { ?C a mon:Bigcountry; mon:name ?N }}";
    Query qu = QueryFactory.create(q);
    QueryExecution qe = QueryExecutionFactory.create(qu, model);
    ResultSet results = qe.execSelect();
    ResultSetFormatter.out(System.out, results, qu);

    Model dedModel = model.getDeductionsModel();
    Model rawModel = model.getRawModel();
    Model diffModel = model.difference(rawModel).difference(dedModel); // = bwd derivations
    System.out.println("---- Derivations (in the DedModel) : ----------------------");
    dedModel.write(System.out,"N3");
    System.out.println("---- Derivations (in the DiffModel) : ----------------------");
    PrintWriter out = new PrintWriter(System.out);
    for (StmtIterator i = diffModel.listStatements(null,
          model.getProperty("http://www.semwebtech.org/mondial/10/meta#bigneighborwith"),
          (RDFNode) null); i.hasNext(); ) {
        Statement s = i.nextStatement();
        out.write("Statement is " + s + "\n");
        for (Iterator<Derivation> i2 = model.getDerivation(s); i2.hasNext(); ) {
            Derivation deriv = (Derivation) i2.next();
            deriv.printTrace(out, true);
        } }
    out.flush();
  } }
