/** * Returns true if it was cleaned, or false if the clause was unsatisfiable * * @param sample * @return */ public static ValueSet<NodeValue> toValueSet(Sample<NodeValue> sample) { if (sample.getPositives().size() > 1 || (!sample.getPositives().isEmpty() && sample.getNegatives().containsAll(sample.getPositives()))) { /** * If there are .) multiple positive constants in a clause, such as in [?x = a, ?x = b] .) or * the negatives contain the positive, such as in [?x = a, !(?x = a)] then the clause is * unsatisfiable and no value contraint can be derived */ return ValueSet.create(); } if (!sample.getPositives().isEmpty()) { /** * Just in case deal with the case [?x = a, !(?x = b)] ---> [?x = a] * * <p>So positive takes precedence over negative */ sample.getNegatives().clear(); } return sample.getPositives().isEmpty() ? ValueSet.create(sample.getNegatives(), false) : ValueSet.create(sample.getPositives(), true); }
public static Map<Var, ValueSet<NodeValue>> extractValueConstraintsDnfClause( Set<Expr> dnfClause) { Map<Var, Sample<NodeValue>> tmp = new HashMap<Var, Sample<NodeValue>>(); for (Expr expr : dnfClause) { boolean isNegative = (expr instanceof E_LogicalNot); if (isNegative) { expr = ((E_LogicalNot) expr).getArg(); } if (!(expr instanceof E_Equals)) { continue; } Pair<Var, NodeValue> constraint = extractValueConstraint(expr); if (constraint == null) { continue; } Sample<NodeValue> sample = tmp.get(constraint.getKey()); if (sample == null) { sample = Sample.create(); tmp.put(constraint.getKey(), sample); } if (isNegative) { sample.getNegatives().add(constraint.getValue()); } else { sample.getPositives().add(constraint.getValue()); } } Map<Var, ValueSet<NodeValue>> result = new HashMap<Var, ValueSet<NodeValue>>(); // Phase 2: Create the value sets for (Map.Entry<Var, Sample<NodeValue>> entry : tmp.entrySet()) { ValueSet<NodeValue> valueSet = toValueSet(entry.getValue()); if (valueSet.isUnknown()) { continue; } result.put(entry.getKey(), valueSet); } return result; }
/** * Searches for expression of the form ?var = const * * <p>TODO We are not considering equals between variables. A space efficient way to achieve this * is by creating a new expression, where the substitution ?x ?y has been applied. * * <p>?x = const . ?y = const . ?x = ?y . * * @param clause * @return */ public static Map<Var, ValueSet<NodeValue>> extractValueConstraintsDnf(Set<Set<Expr>> dnf) { Map<Var, ValueSet<NodeValue>> result = null; if (dnf == null) { return result; } for (Set<Expr> clause : dnf) { Map<Var, ValueSet<NodeValue>> map = extractValueConstraintsDnfClause(clause); if (result == null) { result = map; continue; } Iterator<Map.Entry<Var, ValueSet<NodeValue>>> itEntry = result.entrySet().iterator(); // for(Map.Entry<Var, ValueSet<NodeValue>> entry : result.entrySet()) { while (itEntry.hasNext()) { Map.Entry<Var, ValueSet<NodeValue>> entry = itEntry.next(); ValueSet<NodeValue> a = entry.getValue(); ValueSet<NodeValue> b = map.get(entry.getKey()); a.merge(b); if (a.isUnknown()) { itEntry.remove(); } } if (result.isEmpty()) { break; } } return (result == null) ? new HashMap<Var, ValueSet<NodeValue>>() : result; }
/** * Build JSON with the help of XContentBuilder. * * @param map the map holding the JSON object * @throws IOException */ public void build(Map<String, Object> map) throws IOException { builder.startObject(); for (String k : map.keySet()) { builder.field(k); Object o = map.get(k); if (o instanceof ValueSet) { ((ValueSet) o).build(builder); } else if (o instanceof Map) { build((Map<String, Object>) o); } else { throw new IllegalArgumentException("?"); } } builder.endObject(); }