private ProvaLiteral[] rebuildNewGoals(final ProvaDerivationNode node) { if (target.getBody() == null || target.getBody().length == 0) return new ProvaLiteral[0]; boolean allGround = true; for (ProvaVariable var : targetVariables) { if (!var.getRecursivelyAssigned().isGround()) { allGround = false; break; } } final ProvaLiteral[] body = target.getGuardedBody(source.getBody()[0]); final int bodyLength = body == null ? 0 : body.length; final ProvaLiteral[] goals = new ProvaLiteralImpl[bodyLength]; for (int i = 0; i < bodyLength; i++) { if ("cut".equals(body[i].getPredicate().getSymbol())) { final ProvaVariablePtr any = (ProvaVariablePtr) body[i].getTerms().getFixed()[0]; final ProvaConstantImpl cutnode = ProvaConstantImpl.create(node); if (any.getRuleId() == source.getRuleId()) sourceVariables.get(any.getIndex()).setAssigned(cutnode); else targetVariables.get(any.getIndex()).setAssigned(cutnode); goals[i] = new ProvaLiteralImpl( body[i].getPredicate(), ProvaListImpl.create(new ProvaObject[] {cutnode})); continue; } goals[i] = body[i].rebuild(this); goals[i].setLine(body[i].getLine()); if (allGround) goals[i].setGround(true); } return goals; }
/** 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); }
@Override public boolean targetUnchanged() { for (ProvaVariable var : targetVariables) { if (var.getAssigned() != null && (!(var.getAssigned() instanceof ProvaVariable) || var.getType() != ((ProvaVariable) var.getAssigned()).getType())) return false; } return true; }
/** 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); }
private boolean matchMetadata(final ProvaLiteral sourceLiteral, final ProvaRule target) { Map<String, List<Object>> sourceMetadata = sourceLiteral.getMetadata(); if (sourceMetadata == null || sourceMetadata.size() == 0) // No source metadata or only line number return true; Map<String, List<Object>> targetMetadata = target.getMetadata(); if (targetMetadata == null) return false; // All requested metadata must be found in the target for (Entry<String, List<Object>> s : sourceMetadata.entrySet()) { List<Object> value = targetMetadata.get(s.getKey()); List<Object> sValue = s.getValue(); if (value == null) return false; boolean matched = false; // Either of values in the source must be present in the list of values in the target for (Object vo : value) { if (!(vo instanceof String)) continue; String v = (String) vo; for (Object sVo : sValue) { if (!(sVo instanceof String)) continue; String sV = (String) sVo; if (sV.length() != 0 && Character.isUpperCase(sV.charAt(0))) { if (meta == null) // Should not normally happen return false; for (ProvaList m : meta) { ProvaObject[] mo = m.getFixed(); String varName = (String) ((ProvaConstant) mo[0]).getObject(); ProvaObject var = mo[1]; if (varName.equals(sV)) { if (mo[1] instanceof ProvaVariablePtr) { ProvaVariablePtr varPtr = (ProvaVariablePtr) var; var = sourceVariables.get(varPtr.getIndex()).getRecursivelyAssigned(); } if (var instanceof ProvaVariable) { ((ProvaVariable) var).setAssigned(ProvaConstantImpl.create(v)); matched = true; break; } else if (var instanceof ProvaConstant) { // This allows for dynamic instantiation of metadata values from bound variables sV = (String) ((ProvaConstant) var).getObject(); break; } } } } if (matched) break; if (v.equals(sV)) { matched = true; break; } } if (matched) break; } if (!matched) return false; } return true; }
private ProvaRule rebuild(final ProvaRule newQuery) { final int size = sourceVariables.size(); if (size == 0) return newQuery; final ProvaVariablePtr[] varsMap = new ProvaVariablePtr[size]; final List<ProvaVariable> newVariables = newQuery.getVariables(); int index = 0; for (int i = 0; i < size; i++) { if (sourceVariables.get(i).getAssigned() == null) { varsMap[i] = new ProvaVariablePtrImpl(0, index); ProvaVariable newVariable = sourceVariables.get(i); // .clone(); newVariable.setIndex(index++); newVariable.setRuleId(0); newVariables.add(newVariable); } } newQuery.substituteVariables(varsMap); return newQuery; }
@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; }
@Override public ProvaObject rebuildSource(final ProvaVariablePtr variablePtr) { final ProvaVariable variable = getVariableFromVariablePtr(variablePtr); final ProvaObject assigned = variable.getRecursivelyAssigned(); if (assigned == variable && variablePtr.getRuleId() == sourceRuleId) return variablePtr; if (assigned.getClass() == ProvaConstantImpl.class) return assigned; if (assigned instanceof ProvaVariable) { if (((ProvaVariable) assigned).getRuleId() == targetRuleId) { // This is a target variable so add it to the source variables int index = assigned.collectVariables(targetRuleId, sourceVariables); return new ProvaVariablePtrImpl(sourceRuleId, index); } else { return new ProvaVariablePtrImpl(sourceRuleId, ((ProvaVariable) assigned).getIndex()); } } else if (assigned instanceof ProvaList) { return ((ProvaList) assigned).rebuildSource(this); } else if (assigned instanceof ProvaListPtr) { return ((ProvaListPtr) assigned).rebuildSource(this); } else if (assigned instanceof ProvaMapImpl) { return ((ProvaMapImpl) assigned).rebuildSource(this); } return assigned; }
private boolean isSourceSubstituted() { for (ProvaVariable variable : sourceVariables) if (variable.getAssigned() != null) return true; return false; }