/** Unify goal: pred1(X,[1|Z]|Z) rule: pred1(V,[1,2,3,4],2,3|U):-pred2(V|U). */ @Test public void unifyNonEmptyListTest() { ProvaKnowledgeBase kb = new ProvaKnowledgeBaseImpl(); ProvaConstant c1 = ProvaConstantImpl.create(1); ProvaVariable z = ProvaVariableImpl.create("Z"); ProvaList l1 = ProvaListImpl.create(new ProvaObject[] {c1}, z); ProvaVariable x = ProvaVariableImpl.create("X"); ProvaList l2 = ProvaListImpl.create(new ProvaObject[] {x, l1}, z); ProvaLiteral query = kb.generateLiteral("pred1", l2); ProvaRule goal = kb.generateGoal(new ProvaLiteral[] {query}); ProvaConstant c2 = ProvaConstantImpl.create(2); ProvaConstant c3 = ProvaConstantImpl.create(3); ProvaConstant c4 = ProvaConstantImpl.create(4); ProvaList l3 = ProvaListImpl.create(new ProvaObject[] {c1, c2, c3, c4}); ProvaVariable v = ProvaVariableImpl.create("V"); ProvaVariable u = ProvaVariableImpl.create("U"); ProvaList l4 = ProvaListImpl.create(new ProvaObject[] {v, l3, c2, c3}, u); ProvaLiteral lit1 = kb.generateLiteral("pred1", l4); ProvaList l5 = ProvaListImpl.create(new ProvaObject[] {v}, u); ProvaLiteral lit2 = kb.generateLiteral("pred2", l5); ProvaRule rule = kb.generateRule(lit1, new ProvaLiteral[] {lit2}); ProvaUnificationImpl unification = new ProvaUnificationImpl(goal, rule); boolean result = unification.unify(); org.junit.Assert.assertTrue(result); int countSourceSubstitutions = 0; for (ProvaVariable var : unification.getSourceVariables()) { ProvaObject to = var.getRecursivelyAssigned(); if (to != var) { countSourceSubstitutions++; } } org.junit.Assert.assertEquals(countSourceSubstitutions, 1); int countTargetSubstitutions = 0; for (ProvaVariable var : unification.getTargetVariables()) { ProvaObject to = var.getRecursivelyAssigned(); if (to != var) { countTargetSubstitutions++; } } org.junit.Assert.assertEquals(countTargetSubstitutions, 2); // Recover actual substitutions resulting from the unification ProvaLiteral[] newGoals = unification.rebuildNewGoals(); org.junit.Assert.assertNotNull(newGoals); // There is one actual goal: pred2(X,4) org.junit.Assert.assertEquals(newGoals.length, 1); // The goal literal has fixed arity of 2 org.junit.Assert.assertEquals(newGoals[0].getTerms().computeSize(), 2); // The "fixed" part of the goal literal has length equal to 2 org.junit.Assert.assertEquals(newGoals[0].getTerms().getFixed().length, 2); }
/** Unify goal: pred1(X,[2|A]|Z) rule: pred1(V,Y,3,Y,U):-pred2(V|Y). */ @Test public void unifyTest2() { ProvaKnowledgeBase kb = new ProvaKnowledgeBaseImpl(); ProvaConstant c2 = ProvaConstantImpl.create(2); ProvaVariable a = ProvaVariableImpl.create("A"); ProvaList l1 = ProvaListImpl.create(new ProvaObject[] {c2}, a); ProvaVariable x = ProvaVariableImpl.create("X"); ProvaVariable z = ProvaVariableImpl.create("Z"); ProvaList l2 = ProvaListImpl.create(new ProvaObject[] {x, l1}, z); ProvaLiteral query = kb.generateLiteral("pred1", l2); ProvaRule goal = kb.generateGoal(new ProvaLiteral[] {query}); ProvaVariable v = ProvaVariableImpl.create("V"); ProvaVariable y = ProvaVariableImpl.create("Y"); ProvaConstant c4 = ProvaConstantImpl.create(3); ProvaVariable u = ProvaVariableImpl.create("U"); ProvaList l3 = ProvaListImpl.create(new ProvaObject[] {v, y, c4, y, u}); ProvaLiteral lit1 = kb.generateLiteral("pred1", l3); ProvaList l4 = ProvaListImpl.create(new ProvaObject[] {v}, y); ProvaLiteral lit3 = kb.generateLiteral("pred2", l4); ProvaRule rule = kb.generateRule(lit1, new ProvaLiteral[] {lit3}); ProvaUnificationImpl unification = new ProvaUnificationImpl(goal, rule); boolean result = unification.unify(); org.junit.Assert.assertTrue(result); int countSourceSubstitutions = 0; for (ProvaVariable var : unification.getSourceVariables()) { ProvaObject to = var.getRecursivelyAssigned(); if (to != var) { countSourceSubstitutions++; } } org.junit.Assert.assertEquals(countSourceSubstitutions, 1); int countTargetSubstitutions = 0; for (ProvaVariable var : unification.getTargetVariables()) { ProvaObject to = var.getRecursivelyAssigned(); if (to != var) { countTargetSubstitutions++; } } org.junit.Assert.assertEquals(countTargetSubstitutions, 2); // Recover actual substitutions resulting from the unification ProvaLiteral[] newGoals = unification.rebuildNewGoals(); org.junit.Assert.assertNotNull(newGoals); // There is one actual goal: pred2(X,2|A) org.junit.Assert.assertEquals(newGoals.length, 1); // The goal literal has variable arity org.junit.Assert.assertEquals(newGoals[0].getTerms().computeSize(), -1); // The second argument "2" is added to the "fixed" part of the goal literal org.junit.Assert.assertEquals(newGoals[0].getTerms().getFixed().length, 2); }
@Override // TODO: recursive expressions as operands public boolean process( ProvaReagent prova, ProvaDerivationNode node, ProvaGoal goal, List<ProvaLiteral> newLiterals, ProvaRule query) { ProvaLiteral literal = goal.getGoal(); List<ProvaVariable> variables = query.getVariables(); ProvaList terms = (ProvaList) literal.getTerms().cloneWithVariables(variables); ProvaObject[] data = terms.getFixed(); if (data.length != 3) return false; ProvaObject lt = data[0]; if (lt instanceof ProvaVariablePtr) { ProvaVariablePtr varPtr = (ProvaVariablePtr) lt; lt = variables.get(varPtr.getIndex()).getRecursivelyAssigned(); } if (!((lt instanceof ProvaVariable) || (lt instanceof ProvaConstant))) return false; ProvaObject a1 = data[1]; if (a1 instanceof ProvaVariablePtr) { ProvaVariablePtr varPtr = (ProvaVariablePtr) a1; a1 = variables.get(varPtr.getIndex()).getRecursivelyAssigned(); } if (!(a1 instanceof ProvaConstant)) return false; Object oa1 = ((ProvaConstant) a1).getObject(); if (!(oa1 instanceof Number)) return false; ProvaObject a2 = data[2]; if (a2 instanceof ProvaVariablePtr) { ProvaVariablePtr varPtr = (ProvaVariablePtr) a2; a2 = variables.get(varPtr.getIndex()).getRecursivelyAssigned(); } if (!(a2 instanceof ProvaConstant)) return false; Object oa2 = ((ProvaConstant) a2).getObject(); if (!(oa2 instanceof Number)) return false; Number na1 = (Number) oa1; Number na2 = (Number) oa2; Number result; if (na1 instanceof Double || na2 instanceof Double) result = na1.doubleValue() * na2.doubleValue(); else if (na1 instanceof Float || na2 instanceof Float) result = na1.floatValue() * na2.floatValue(); else if (na1 instanceof Long || na2 instanceof Long) result = na1.longValue() * na2.longValue(); else if (na1 instanceof Integer || na2 instanceof Integer) result = na1.intValue() * na2.intValue(); else result = na1.byteValue() * na2.byteValue(); if (lt instanceof ProvaConstant) return ((ProvaConstant) lt).getObject() == result; ((ProvaVariable) lt).setAssigned(ProvaConstantImpl.create(result)); return true; }