public EnvironmentDomain <K, V> Join(EnvironmentDomain <K, V> that, bool widening, out bool weaker) { //todo: remove it weaker = false; if (map == that.map || IsTop) { return(this); } if (that.IsTop) { weaker = !IsTop; return(that); } if (IsBottom) { weaker = !that.IsBottom; return(that); } if (that.IsBottom) { return(this); } IImmutableMap <K, V> min; IImmutableMap <K, V> max; GetMinAndMaxByCount(map, that.map, out min, out max); var intersect = min; foreach (var key in min.Keys) { if (!max.ContainsKey(key)) { intersect = intersect.Remove(key); } else { bool keyWeaker; var join = min[key].Join(max[key], widening, out keyWeaker); if (keyWeaker) { weaker = true; intersect = join.IsTop ? intersect.Remove(key) : intersect.Add(key, join); } } } weaker |= intersect.Count < map.Count; return(new EnvironmentDomain <K, V> (intersect)); }
public bool LessEqual(EnvironmentDomain <K, V> that) { if (that.IsTop || IsBottom) { return(true); } if (IsTop || that.IsBottom || this.map.Count < that.map.Count) { return(false); } return(that.map.Keys.All(key => this.map.ContainsKey(key) && this.map [key].LessEqual(that.map [key]))); }
public bool LessEqual(EnvironmentDomain <K, V> that) { bool result; if (this.TryTrivialLessEqual(that, out result)) { return(result); } if (map.Count < that.map.Count) { return(false); } return(that.map.Keys.All(key => map.ContainsKey(key) && map[key].LessEqual(that.map[key]))); }
public EnvironmentDomain <K, V> Meet(EnvironmentDomain <K, V> that) { if (this.map == that.map) { return(this); } if (IsTop) { return(that); } if (that.IsTop || IsBottom) { return(this); } if (that.IsBottom) { return(that); } IImmutableMap <K, V> min; IImmutableMap <K, V> max; GetMinAndMaxByCount(this.map, that.map, out min, out max); IImmutableMap <K, V> union = max; foreach (K key in min.Keys) { if (!max.ContainsKey(key)) { union = union.Add(key, min [key]); } else { V meet = min [key].Meet(max [key]); union = union.Add(key, meet); } } return(new EnvironmentDomain <K, V> (union)); }
EnvironmentDomain <K, V> JoinOrWiden(EnvironmentDomain <K, V> that, Func <V, V, V> op) { if (ReferenceEquals(map, that.map) || IsBottom) { return(that); } if (that.IsBottom) { return(this); } IImmutableMap <K, V> min; IImmutableMap <K, V> max; GetMinAndMaxByCount(map, that.map, out min, out max); var result = min; // intersection of keys foreach (var key in min.Keys) { V thatValue; if (max.TryGetValue(key, out thatValue)) { var join = op(min[key], thatValue); if (join.IsBottom) { return(Bottom); } result = join.IsTop ? result.Remove(key) : result.Add(key, join); } else { result = result.Remove(key); } } return(new EnvironmentDomain <K, V> (result)); }
public EnvironmentDomain <K, V> Widen(EnvironmentDomain <K, V> that) { return(JoinOrWiden(that, (a, b) => a.Widen(b))); }