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; }
@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; }