};
final List<RDFDataset.Quad> unmatched = new ArrayList<RDFDataset.Quad>();
final BnodeMappings bnodeMaps = new BnodeMappings();
boolean finalpass = false;
while (!exp.isEmpty() && !res.isEmpty()) {
final Quad eq = exp.remove(0);
int matches = 0;
RDFDataset.Quad last_match = null;
for (final RDFDataset.Quad rq : res) {
// if predicates are not equal there cannot be a match
if (!eq.getPredicate().equals(rq.getPredicate())) {
continue;
}
if (eq.getSubject().isBlankNode() && rq.getSubject().isBlankNode()) {
// check for locking
boolean subjectLocked = false;
if (bnodeMaps.isLocked(eq.getSubject().getValue())) {
// if this mapping doesn't match the locked mapping, we
// don't have a match
if (!rq.getSubject().getValue()
.equals(bnodeMaps.getMapping(eq.getSubject().getValue()))) {
continue;
}
subjectLocked = true;
}
// if the objects are also both blank nodes
if (eq.getObject().isBlankNode() && rq.getObject().isBlankNode()) {
// check for locking
if (bnodeMaps.isLocked(eq.getObject().getValue())) {
// if this mapping doesn't match the locked mapping,
// we don't have a match
if (!rq.getObject().getValue()
.equals(bnodeMaps.getMapping(eq.getObject().getValue()))) {
continue;
}
} else {
// add possible mappings for the objects
bnodeMaps.addPossibleMapping(eq.getObject().getValue(), rq.getObject()
.getValue());
}
}
// otherwise, if the objects aren't equal we can't have a
// match
else if (!eq.getObject().equals(rq.getObject())) {
continue;
}
// objects are equal or both blank nodes so we have a match
matches++;
last_match = rq;
// if subject is not locked add a possible mapping between
// subjects
if (!subjectLocked) {
bnodeMaps.addPossibleMapping(eq.getSubject().getValue(), rq.getSubject()
.getValue());
}
}
// otherwise check if the subjects are equal
else if (eq.getSubject().equals(rq.getSubject())) {
// if both objects are blank nodes, add possible mappings
// for them
if (eq.getObject().isBlankNode() && rq.getObject().isBlankNode()) {
// check for locking
if (bnodeMaps.isLocked(eq.getObject().getValue())) {
// if this mapping doesn't match the locked mapping,
// we don't have a match
if (!rq.getObject().getValue()
.equals(bnodeMaps.getMapping(eq.getObject().getValue()))) {
continue;
}
} else {
// add possible mappings for the objects
bnodeMaps.addPossibleMapping(eq.getObject().getValue(), rq.getObject()
.getValue());
}
// if we get here we have a match
matches++;
last_match = rq;
}
// otherwise, if the objects are equal we we have an exact
// match
else if (eq.getObject().equals(rq.getObject())) {
matches = 1;
last_match = rq;
break;
}
}
}
if (matches == 0) {
// if we didn't find any matches, we're done and things didn't
// match!
return false;
} else if (matches == 1) {
// we have one match
if (eq.getSubject().isBlankNode()) {
// lock this mapping
bnodeMaps.lockMapping(eq.getSubject().getValue(), last_match.getSubject()
.getValue());
}
if (eq.getObject().isBlankNode()) {
// lock this mapping
bnodeMaps.lockMapping(eq.getObject().getValue(), last_match.getObject()
.getValue());
}
res.remove(last_match);
} else {
// we got multiple matches, we need to figure this stuff out