in libraries/AdaptiveExpressions/TriggerTrees/Clause.cs [117:210]
public RelationshipType Relationship(Clause other, Dictionary<string, IPredicateComparer> comparers)
{
var soFar = RelationshipType.Incomparable;
var shorter = this;
var shorterCount = shorter.Children.Length;
var longer = other;
var longerCount = longer.Children.Length;
var swapped = false;
if (longerCount < shorterCount)
{
longer = this;
shorter = other;
var tmp = longerCount;
longerCount = shorterCount;
shorterCount = tmp;
swapped = true;
}
if (shorterCount == 0)
{
if (longerCount == 0)
{
soFar = RelationshipType.Equal;
}
else
{
soFar = RelationshipType.Generalizes;
}
}
else
{
// If every one of shorter predicates is equal or superset of one in longer, then shorter is a superset of longer
foreach (var shortPredicate in shorter.Children)
{
var shorterRel = RelationshipType.Incomparable;
foreach (var longPredicate in longer.Children)
{
shorterRel = Relationship(shortPredicate, longPredicate, comparers);
if (shorterRel != RelationshipType.Incomparable)
{
// Found related predicates
break;
}
}
if (shorterRel == RelationshipType.Incomparable)
{
// Predicate in shorter is incomparable so done
soFar = RelationshipType.Incomparable;
break;
}
else
{
if (soFar == RelationshipType.Incomparable)
{
soFar = shorterRel;
}
if (soFar == RelationshipType.Equal)
{
if (shorterRel == RelationshipType.Generalizes
|| (shorterRel == RelationshipType.Specializes && shorterCount == longerCount)
|| shorterRel == RelationshipType.Equal)
{
soFar = shorterRel;
}
else
{
break;
}
}
else if (soFar != shorterRel)
{
// Not continued with sub/super so incomparable
break;
}
}
}
if (shorterCount != longerCount)
{
switch (soFar)
{
case RelationshipType.Equal:
case RelationshipType.Generalizes: soFar = RelationshipType.Generalizes; break;
default: soFar = RelationshipType.Incomparable; break;
}
}
soFar = BindingsRelationship(soFar, shorter, longer);
}
return swapped ? soFar.Swap() : soFar;
}