boolean (@NotNull DfaValue dfaLeft, DfaValue dfaRight) { if (getDfType(dfaLeft).meet(getDfType(dfaRight)) == DfType.BOTTOM) return true; List<DerivedVariableDescriptor> variables = new ArrayList<>(dfaLeft.getDfType().getDerivedVariables()); variables.retainAll(dfaRight.getDfType().getDerivedVariables()); return StreamEx.of(variables) .filter(dv -> dv.equalityImpliesQualifierEquality()) .allMatch(dv -> { DfaValue derivedLeft = dv.createValue(myFactory, dfaLeft); DfaValue derivedRight = dv.createValue(myFactory, dfaRight); DfType leftType = getDfType(derivedLeft); DfType rightType = getDfType(derivedRight); if (leftType instanceof DfConstantType && leftType.equals(rightType)) return false; return derivedLeft.getDfType().hasNonStandardEquivalence() || derivedRight.getDfType().hasNonStandardEquivalence() || applyRelation(derivedLeft, derivedRight, true); }); }