public void testDisjunctionVariable() {
    PrologEngine engine = setupDisjunction();

    Variable variableY = new Variable("Y");
    Result result3 = engine.askQuestion(new Predicate("hello", 1, variableY));

    assertTrue(result3.hasAnswer());
    assertEquals(new Constant("world"), variableY.getBinding());

    result3.next();
    assertTrue(result3.hasAnswer());
    assertEquals(new Constant("mars"), variableY.getBinding());

    result3.next();
    assertTrue(result3.hasAnswer());
    assertEquals(new Constant("venus"), variableY.getBinding());
  }
 /** Writes the debug dump of the table into logs. Not thread-safe. */
 public void debugDumpTable() {
   StringBuilder dump = new StringBuilder(keysAssigned + " keys\n");
   TreeMap<Long, Integer> byteIntervals = new TreeMap<Long, Integer>();
   int examined = 0;
   for (int slot = 0; slot < refs.length; ++slot) {
     long ref = refs[slot];
     if (ref == 0) {
       continue;
     }
     ++examined;
     long recOffset = getFirstRecordLengthsOffset(ref, null);
     long tailOffset = Ref.getOffset(ref);
     writeBuffers.setReadPoint(recOffset);
     int valueLength = (int) writeBuffers.readVLong(), keyLength = (int) writeBuffers.readVLong();
     long ptrOffset = writeBuffers.getReadPoint();
     if (Ref.hasList(ref)) {
       byteIntervals.put(recOffset, (int) (ptrOffset + 5 - recOffset));
     }
     long keyOffset = tailOffset - valueLength - keyLength;
     byte[] key = new byte[keyLength];
     WriteBuffers.ByteSegmentRef fakeRef = new WriteBuffers.ByteSegmentRef(keyOffset, keyLength);
     byteIntervals.put(keyOffset - 4, keyLength + 4);
     writeBuffers.populateValue(fakeRef);
     System.arraycopy(fakeRef.getBytes(), (int) fakeRef.getOffset(), key, 0, keyLength);
     dump.append(Utils.toStringBinary(key, 0, key.length))
         .append(" ref [")
         .append(dumpRef(ref))
         .append("]: ");
     Result hashMapResult = new Result();
     getValueResult(key, 0, key.length, hashMapResult);
     List<WriteBuffers.ByteSegmentRef> results = new ArrayList<WriteBuffers.ByteSegmentRef>();
     WriteBuffers.ByteSegmentRef byteSegmentRef = hashMapResult.first();
     while (byteSegmentRef != null) {
       results.add(hashMapResult.byteSegmentRef);
       byteSegmentRef = hashMapResult.next();
     }
     dump.append(results.size()).append(" rows\n");
     for (int i = 0; i < results.size(); ++i) {
       WriteBuffers.ByteSegmentRef segment = results.get(i);
       byteIntervals.put(
           segment.getOffset(),
           segment.getLength() + ((i == 0) ? 1 : 0)); // state byte in the first record
     }
   }
   if (examined != keysAssigned) {
     dump.append("Found " + examined + " keys!\n");
   }
   // Report suspicious gaps in writeBuffers
   long currentOffset = 0;
   for (Map.Entry<Long, Integer> e : byteIntervals.entrySet()) {
     long start = e.getKey(), len = e.getValue();
     if (start - currentOffset > 4) {
       dump.append("Gap! [" + currentOffset + ", " + start + ")\n");
     }
     currentOffset = start + len;
   }
   LOG.info("Hashtable dump:\n " + dump.toString());
 }
  public void testConjunctionBacktrackingVariable() {
    PrologEngine engine = setupConjunctionBacktracking();

    Variable variableX = new Variable("X");

    Predicate question = new Predicate("suitable", 1, variableX);
    Result answer = engine.askQuestion(question);
    assertTrue(answer.hasAnswer());
    assertEquals(new Constant("Eric"), variableX.getBinding());
    answer.next();
    assertFalse("Only one answer expected", answer.hasAnswer());
  }
  public void testConjunctionVariable() {
    PrologEngine engine = setupConjunction();

    Variable variableX = new Variable("X");
    Variable variableY = new Variable("Y");
    Variable variableZ = new Variable("Z");

    Predicate question = new Predicate("three", 3, variableX, variableY, variableZ);
    Result answer = engine.askQuestion(question);
    assertTrue(answer.hasAnswer());
    assertEquals(new Constant("one"), variableX.getBinding());
    assertEquals(new Constant("two"), variableY.getBinding());
    assertEquals(new Constant("two"), variableZ.getBinding());
    answer.next();
    assertFalse(answer.hasAnswer());
  }