anchor.diff:        //
         // we can add
         //
  -      // * a [0, 1) is incompatible with c [1, 2)
  -      var mergedMatching = _mergeDeps(incompatibilities
  -          .map((incompatibility) => _matching(incompatibility, fact.allowed)));
  -      if (mergedMatching == null ||
  -          !mergedMatching.constraint.allowsAll(fact.allowed.constraint)) {
  -        continue;
  -      }
  -
  -      var mergedNonMatching = _intersectDeps(incompatibilities.map(
  -          (incompatibility) => _nonMatching(incompatibility, fact.allowed)));
  -      if (mergedNonMatching == null) continue;
  -      _forCurrent.add(new Incompatibility(fact.depender, mergedNonMatching,
  +      // * a [0, 1) is incompatible with c [1, 3)
  +      var incompatible = _transitiveIncompatible(
  +          fact.allowed, incompatibilities);
  +      if (incompatible == null) continue;
  +
  +      _forCurrent.add(new Incompatibility(fact.depender, incompatible,
             incompatibilities.toList()..add(fact)));
       }
     }
  
positive.code:     return _mergeDeps(dependencies.map((dependency) => dependency.allowed));
    }
  
    /// Returns the dependency in [incompatibility] whose name matches [dep].
    PackageDep _matching(Incompatibility incompatibility, PackageDep dep) =>
        incompatibility.dep1.name == dep.name
  
negative.code:         if (!_incompatibilityIntoIncompatibilities(fact)) continue;
          if (!_incompatibilityIntoDisallowed(fact)) continue;
          if (!_incompatibilityIntoRequired(fact)) continue;
          if (!_incompatibilityIntoDependencies(fact)) continue;
  
          _incompatibilities
              .putIfAbsent(fact.dep1.toRef(), () => new Set())
  