public final IBindingSet newBindingSet(final IRule rule) {

    final IBindingSet constants = rule.getConstants();

    final int nconstants = constants.size();

    final IBindingSet bindingSet = new ListBindingSet()
        //                new ArrayBindingSet(rule.getVariableCount()+ nconstants)
        ;

    if (nconstants > 0) {

      /*
       * Bind constants declared by the rule before returning the binding
       * set to the caller.
       */

      final Iterator<Map.Entry<IVariable, IConstant>> itr = constants.iterator();

      while (itr.hasNext()) {

        final Map.Entry<IVariable, IConstant> entry = itr.next();

        bindingSet.set(entry.getKey(), entry.getValue());
      }
    }

    return bindingSet;
  }
Exemple #2
0
  /**
   * Constructs the element iff requested, saves the rule reference iff requested, and clones and
   * saves the bindingSet iff requested. The requested behavior depends on {@link
   * IJoinNexus#solutionFlags()}. When requested, the element is created using {@link
   * IRelation#newElement(IPredicate, IBindingSet)} for the {@link IRelation} that is named by the
   * head of the rule.
   *
   * @param e The element.
   * @param rule The rule.
   * @param bindingSet The binding set for this solution. If {@link IJoinNexus#BINDINGS} was
   *     specified, then the binding set will be <em>cloned</em> by this ctor.
   * @throws IllegalArgumentException if any parameter is <code>null</code>.
   */
  @SuppressWarnings("unchecked")
  public Solution(final IJoinNexus joinNexus, final IRule<E> rule, final IBindingSet bindingSet) {

    if (joinNexus == null) throw new IllegalArgumentException();

    if (rule == null) throw new IllegalArgumentException();

    if (bindingSet == null) throw new IllegalArgumentException();

    final int flags = joinNexus.solutionFlags();

    if ((flags & IJoinNexus.ELEMENT) != 0) {

      /*
       * The relation is responsible for how the elements are materialized
       * from the bindings.
       *
       * Note: Caching for this relation is very important!
       */

      // the head of the rule.
      final IPredicate head = rule.getHead();

      // the relation for the head of the rule.
      final IRelation relation = joinNexus.getHeadRelationView(head);

      // use the relation's element factory.
      this.e =
          (E) relation.newElement(head.args(), bindingSet); // TODO BOp.args() is not efficient!

      //            // use the relation's element factory.
      //            this.e = (E) relation.newElement(head, bindingSet);

    } else {

      this.e = null;
    }

    if ((flags & IJoinNexus.BINDINGS) != 0) {

      this.bindingSet = bindingSet.clone();

    } else {

      this.bindingSet = null;
    }

    if ((flags & IJoinNexus.RULE) != 0) {

      this.rule = rule;

    } else {

      this.rule = null;
    }
  }
  /**
   * Return the bound value for the variable.
   *
   * @param v The variable.
   * @param bset The source solution.
   * @param required <code>true</code> iff the variable must be bound.
   * @return The bound value and <code>null</code> if the variable is not bound.
   */
  @SuppressWarnings("rawtypes")
  protected static IV getIV(
      final IVariable<?> var, final IBindingSet bset, final boolean required) {

    @SuppressWarnings("unchecked")
    final IConstant<IV> constant = bset.get(var);

    if (constant == null) {

      if (required) throw new RuntimeException("Variable is not bound: " + var);

      return null;
    }

    final IV _s = (IV) constant.get();

    return _s;
  }
  @SuppressWarnings("unchecked")
  private final void copyValues(
      final IElement e, final IPredicate<?> pred, final IBindingSet bindingSet) {

    for (int i = 0; i < pred.arity(); i++) {

      final IVariableOrConstant<?> t = pred.get(i);

      if (t.isVar()) {

        final IVariable<?> var = (IVariable<?>) t;

        final Constant<?> newval = new Constant(e.get(i));

        bindingSet.set(var, newval);
      }
    }
  }
  /**
   * Creates a {@link Justification}, writes it on the store using {@link
   * RDFJoinNexus#newInsertBuffer(IMutableRelation)}, verifies that we can read it back from the
   * store, and then retracts the justified statement and verifies that the justification was also
   * retracted.
   */
  public void test_writeReadRetract() {

    final Properties properties = super.getProperties();

    // override the default axiom model.
    properties.setProperty(
        com.bigdata.rdf.store.AbstractTripleStore.Options.AXIOMS_CLASS, NoAxioms.class.getName());

    final AbstractTripleStore store = getStore(properties);

    try {

      if (!store.isJustify()) {

        log.warn("Test skipped - justifications not enabled");
      }

      /*
       * the explicit statement that is the support for the rule.
       */

      final IV U = store.addTerm(new URIImpl("http://www.bigdata.com/U"));
      final IV A = store.addTerm(new URIImpl("http://www.bigdata.com/A"));
      final IV Y = store.addTerm(new URIImpl("http://www.bigdata.com/Y"));

      store.addStatements(
          new SPO[] { //
            new SPO(U, A, Y, StatementEnum.Explicit) //
          }, //
          1);

      assertTrue(store.hasStatement(U, A, Y));
      assertEquals(1, store.getStatementCount());

      final InferenceEngine inf = store.getInferenceEngine();

      final Vocabulary vocab = store.getVocabulary();

      // the rule.
      final Rule rule = new RuleRdf01(store.getSPORelation().getNamespace(), vocab);

      final IJoinNexus joinNexus =
          store
              .newJoinNexusFactory(
                  RuleContextEnum.DatabaseAtOnceClosure,
                  ActionEnum.Insert,
                  IJoinNexus.ALL,
                  null /* filter */)
              .newInstance(store.getIndexManager());

      /*
       * The buffer that accepts solutions and causes them to be written
       * onto the statement indices and the justifications index.
       */
      final IBuffer<ISolution[]> insertBuffer = joinNexus.newInsertBuffer(store.getSPORelation());

      // the expected justification (setup and verified below).
      final Justification jst;

      // the expected entailment.
      final SPO expectedEntailment =
          new SPO( //
              A, vocab.get(RDF.TYPE), vocab.get(RDF.PROPERTY), StatementEnum.Inferred);

      {
        final IBindingSet bindingSet = joinNexus.newBindingSet(rule);

        /*
         * Note: rdfs1 is implemented using a distinct term scan. This
         * has the effect of leaving the variables that do not appear in
         * the head of the rule unbound. Therefore we DO NOT bind those
         * variables here in the test case and they will be represented
         * as ZERO (0L) in the justifications index and interpreted as
         * wildcards.
         */
        //                bindingSet.set(Var.var("u"), new Constant<IV>(U));
        bindingSet.set(Var.var("a"), new Constant<IV>(A));
        //                bindingSet.set(Var.var("y"), new Constant<IV>(Y));

        final ISolution solution = new Solution(joinNexus, rule, bindingSet);

        /*
         * Verify the justification that will be built from that
         * solution.
         */
        {
          jst = new Justification(solution);

          /*
           * Verify the bindings on the head of the rule as
           * represented by the justification.
           */
          assertEquals(expectedEntailment, jst.getHead());

          /*
           * Verify the bindings on the tail of the rule as
           * represented by the justification. Again, note that the
           * variables that do not appear in the head of the rule are
           * left unbound for rdfs1 as a side-effect of evaluation
           * using a distinct term scan.
           */
          final SPO[] expectedTail =
              new SPO[] { //
                new SPO(NULL, A, NULL, StatementEnum.Inferred) //
              };

          if (!Arrays.equals(expectedTail, jst.getTail())) {

            fail("Expected: " + Arrays.toString(expectedTail) + ", but actual: " + jst);
          }
        }

        // insert solution into the buffer.
        insertBuffer.add(new ISolution[] {solution});
      }

      //            SPOAssertionBuffer buf = new SPOAssertionBuffer(store, store,
      //                    null/* filter */, 100/* capacity */, true/* justified */);
      //
      //            assertTrue(buf.add(head, jst));

      // no justifications before hand.
      assertEquals(0L, store.getSPORelation().getJustificationIndex().rangeCount());

      // flush the buffer.
      assertEquals(1L, insertBuffer.flush());

      // one justification afterwards.
      assertEquals(1L, store.getSPORelation().getJustificationIndex().rangeCount());

      /*
       * verify read back from the index.
       */
      {
        final ITupleIterator<Justification> itr =
            store.getSPORelation().getJustificationIndex().rangeIterator();

        while (itr.hasNext()) {

          final ITuple<Justification> tuple = itr.next();

          // de-serialize the justification from the key.
          final Justification tmp = tuple.getObject();

          // verify the same.
          assertEquals(jst, tmp);

          // no more justifications in the index.
          assertFalse(itr.hasNext());
        }
      }

      /*
       * test iterator with a single justification.
       */
      {
        final FullyBufferedJustificationIterator itr =
            new FullyBufferedJustificationIterator(store, expectedEntailment);

        assertTrue(itr.hasNext());

        final Justification tmp = itr.next();

        assertEquals(jst, tmp);
      }

      // an empty focusStore.
      final TempTripleStore focusStore =
          new TempTripleStore(store.getIndexManager().getTempStore(), store.getProperties(), store);

      try {

        /*
         * The inference (A rdf:type rdf:property) is grounded by the
         * explicit statement (U A Y).
         */

        assertTrue(
            Justification.isGrounded(
                inf,
                focusStore,
                store,
                expectedEntailment,
                false /* testHead */,
                true /* testFocusStore */,
                new VisitedSPOSet(focusStore.getIndexManager())));

        // add the statement (U A Y) to the focusStore.
        focusStore.addStatements(
            new SPO[] { //
              new SPO(U, A, Y, StatementEnum.Explicit) //
            }, //
            1);

        /*
         * The inference is no longer grounded since we have declared
         * that we are also retracting its grounds.
         */
        assertFalse(
            Justification.isGrounded(
                inf,
                focusStore,
                store,
                expectedEntailment,
                false /* testHead */,
                true /* testFocusStore */,
                new VisitedSPOSet(focusStore.getIndexManager())));

      } finally {

        /*
         * Destroy the temp kb, but not the backing TemporaryStore. That
         * will be destroyed when we destroy the IndexManager associated
         * with the main store (below).
         */
        focusStore.destroy();
      }

      /*
       * remove the justified statements.
       */

      assertEquals(
          1L,
          store
              .getAccessPath(expectedEntailment.s, expectedEntailment.p, expectedEntailment.o)
              .removeAll());

      /*
       * verify that the justification for that statement is gone.
       */
      {
        final ITupleIterator<?> itr =
            store.getSPORelation().getJustificationIndex().rangeIterator();

        assertFalse(itr.hasNext());
      }

    } finally {

      store.__tearDownUnitTest();
    }
  }