Returns a domain whose corresponding set of concrete values include all of the values corresponding to self and other. In effect this behaves like set union.
(&self, other: Rc<SymbolicValue>)
| 979 | /// Returns a domain whose corresponding set of concrete values include all of the values |
| 980 | /// corresponding to self and other. In effect this behaves like set union. |
| 981 | fn join(&self, other: Rc<SymbolicValue>) -> Rc<SymbolicValue> { |
| 982 | // [{} union y] -> y |
| 983 | if self.is_bottom() { |
| 984 | return other; |
| 985 | } |
| 986 | // [TOP union y] -> TOP |
| 987 | if self.is_top() { |
| 988 | return self.clone(); |
| 989 | } |
| 990 | // [x union {}] -> x |
| 991 | if other.is_bottom() { |
| 992 | return self.clone(); |
| 993 | } |
| 994 | // [x union x] -> x |
| 995 | if (*self) == other { |
| 996 | return other; |
| 997 | } |
| 998 | // [x union TOP] -> TOP |
| 999 | if other.is_top() { |
| 1000 | return other; |
| 1001 | } |
| 1002 | // [widened(x) union y] -> widened(x) |
| 1003 | if let Expression::Widen { .. } = &self.expression { |
| 1004 | return self.clone(); |
| 1005 | } |
| 1006 | // [x union widened(y)] -> widened(y) |
| 1007 | if let Expression::Widen { .. } = &other.expression { |
| 1008 | return other.clone(); |
| 1009 | } |
| 1010 | let expression_size = self.expression_size.saturating_add(other.expression_size); |
| 1011 | SymbolicValue::make_from( |
| 1012 | Expression::Join { |
| 1013 | left: self.clone(), |
| 1014 | right: other, |
| 1015 | }, |
| 1016 | expression_size, |
| 1017 | ) |
| 1018 | } |
| 1019 | |
| 1020 | /// Returns an element that is "self <= other". |
| 1021 | fn less_or_equal(&self, other: Rc<SymbolicValue>) -> Rc<SymbolicValue> { |
no test coverage detected