Skip to main content

rapx/analysis/range/domain/
range.rs

1#![allow(unused_imports)]
2#![allow(unused_variables)]
3#![allow(dead_code)]
4#![allow(unused_assignments)]
5#![allow(irrefutable_let_patterns)]
6use std::{default, fmt};
7
8use num_traits::{Bounded, Num, Zero};
9use rust_intervals::Interval;
10use rustc_middle::mir::{BinOp, UnOp};
11use std::ops::{Add, Mul, Sub};
12
13use crate::{
14    analysis::range::{Range, RangeType, domain::symbolic_expr::IntervalTypeTrait},
15    rap_trace,
16};
17
18use super::domain::*;
19
20impl<T> Range<T>
21where
22    T: IntervalArithmetic,
23{
24    // Parameterized constructor
25    pub fn new(lb: T, ub: T, rtype: RangeType) -> Self {
26        Self {
27            rtype,
28            range: Interval::new_closed_closed(lb, ub),
29        }
30    }
31    pub fn default(default: T) -> Self {
32        Self {
33            rtype: RangeType::Unknown,
34
35            range: Interval::new_closed_closed(default, default),
36        }
37    }
38    // Getter for lower bound
39    pub fn init(r: Interval<T>) -> Self {
40        Self {
41            rtype: RangeType::Regular,
42            range: r,
43        }
44    }
45
46    pub fn top() -> Self {
47        Self::new(T::min_value(), T::max_value(), RangeType::Regular)
48    }
49
50    pub fn bottom() -> Self {
51        Self::default(T::min_value())
52    }
53
54    pub fn exact(value: T) -> Self {
55        Self::new(value.clone(), value, RangeType::Regular)
56    }
57
58    pub fn get_lower(&self) -> T {
59        self.range.lower().unwrap().clone()
60    }
61
62    // Getter for upper bound
63    pub fn get_upper(&self) -> T {
64        self.range.upper().unwrap().clone()
65    }
66
67    // Check if the range type is unknown
68    pub fn is_unknown(&self) -> bool {
69        self.rtype == RangeType::Unknown
70    }
71
72    // Set the range type to unknown
73    pub fn set_unknown(&mut self) {
74        self.rtype = RangeType::Unknown;
75    }
76
77    // Check if the range type is regular
78    pub fn is_regular(&self) -> bool {
79        self.rtype == RangeType::Regular
80    }
81
82    // Set the range type to regular
83    pub fn set_regular(&mut self) {
84        self.rtype = RangeType::Regular;
85    }
86
87    // Check if the range type is empty
88    pub fn is_empty(&self) -> bool {
89        self.rtype == RangeType::Empty
90    }
91
92    // Set the range type to empty
93    pub fn set_empty(&mut self) {
94        self.rtype = RangeType::Empty;
95    }
96    pub fn set_default(&mut self) {
97        self.rtype = RangeType::Regular;
98        self.range = Interval::new_closed_closed(T::min_value(), T::max_value());
99    }
100    pub fn add(&self, other: &Range<T>) -> Range<T> {
101        let a = self
102            .get_lower()
103            .clone()
104            .checked_add(&other.get_lower().clone())
105            .unwrap_or(T::max_value());
106
107        let b = self
108            .get_upper()
109            .clone()
110            .checked_add(&other.get_upper().clone())
111            .unwrap_or(T::max_value());
112
113        Range::new(a, b, RangeType::Regular)
114    }
115
116    pub fn sub(&self, other: &Range<T>) -> Range<T> {
117        let a = self
118            .get_lower()
119            .clone()
120            .checked_sub(&other.get_upper().clone())
121            .unwrap_or(T::min_value());
122
123        let b = self
124            .get_upper()
125            .clone()
126            .checked_sub(&other.get_lower().clone())
127            .unwrap_or(T::max_value());
128
129        Range::new(a, b, RangeType::Regular)
130    }
131
132    pub fn mul(&self, other: &Range<T>) -> Range<T> {
133        let candidates = vec![
134            self.get_lower().clone() * other.get_lower().clone(),
135            self.get_lower().clone() * other.get_upper().clone(),
136            self.get_upper().clone() * other.get_lower().clone(),
137            self.get_upper().clone() * other.get_upper().clone(),
138        ];
139        let min = candidates
140            .iter()
141            .cloned()
142            .min_by(|a, b| a.partial_cmp(b).unwrap())
143            .unwrap();
144        let max = candidates
145            .iter()
146            .cloned()
147            .max_by(|a, b| a.partial_cmp(b).unwrap())
148            .unwrap();
149        Range::new(min, max, RangeType::Regular)
150    }
151
152    pub fn intersectwith(&self, other: &Range<T>) -> Range<T> {
153        if self.is_unknown() {
154            return Range::new(
155                other.get_lower().clone(),
156                other.get_upper().clone(),
157                RangeType::Regular,
158            );
159        } else if other.is_unknown() {
160            return Range::new(
161                self.get_lower().clone(),
162                self.get_upper().clone(),
163                RangeType::Regular,
164            );
165        } else {
166            let result = self.range.clone().intersection(&other.range.clone());
167            let mut range = Range::bottom();
168
169            if let r = result {
170                range = Range::init(r);
171                range
172            } else {
173                range
174            }
175        }
176    }
177
178    pub fn unionwith(&self, other: &Range<T>) -> Range<T> {
179        if self.is_unknown() {
180            return Range::new(
181                other.get_lower().clone(),
182                other.get_upper().clone(),
183                RangeType::Regular,
184            );
185        } else if other.is_unknown() {
186            return Range::new(
187                self.get_lower().clone(),
188                self.get_upper().clone(),
189                RangeType::Regular,
190            );
191        } else {
192            let left = std::cmp::min_by(self.get_lower(), other.get_lower(), |a, b| {
193                a.partial_cmp(b).unwrap()
194            });
195            let right = std::cmp::max_by(self.get_upper(), other.get_upper(), |a, b| {
196                a.partial_cmp(b).unwrap()
197            });
198            Range::new(left.clone(), right.clone(), RangeType::Regular)
199        }
200    }
201}
202
203pub trait Lattice {
204    fn widen(&self, other: &Self) -> Self;
205    fn narrow(&self, other: &Self) -> Self;
206}
207
208impl<T> Range<T>
209where
210    T: IntervalArithmetic,
211{
212    pub fn widen(&self, other: &Range<T>) -> Range<T> {
213        if self.is_unknown() {
214            return other.clone();
215        }
216        let a_lower = self.get_lower();
217        let a_upper = self.get_upper();
218        let b_lower = other.get_lower();
219        let b_upper = other.get_upper();
220
221        if b_lower < a_lower && b_upper > a_upper {
222            Range::top()
223        } else if b_lower < a_lower {
224            Range::new(T::min_value(), a_upper.clone(), RangeType::Regular)
225        } else if b_upper > a_upper {
226            Range::new(a_lower.clone(), T::max_value(), RangeType::Regular)
227        } else {
228            self.clone()
229        }
230    }
231
232    pub fn narrow(&self, other: &Range<T>) -> Range<T> {
233        let a_lower = self.get_lower();
234        let a_upper = self.get_upper();
235        let b_lower = other.get_lower();
236        let b_upper = other.get_upper();
237
238        let final_lower = if a_lower == T::min_value() && b_lower > T::min_value() {
239            b_lower.clone()
240        } else if a_lower <= b_lower {
241            b_lower.clone()
242        } else {
243            a_lower.clone()
244        };
245
246        let final_upper = if a_upper == T::max_value() && b_upper < T::max_value() {
247            b_upper.clone()
248        } else if a_upper >= b_upper {
249            b_upper.clone()
250        } else {
251            a_upper.clone()
252        };
253
254        Range::new(final_lower, final_upper, RangeType::Regular)
255    }
256}
257
258impl<T: IntervalArithmetic> Lattice for Range<T> {
259    fn widen(&self, other: &Range<T>) -> Range<T> {
260        Range::widen(self, other)
261    }
262
263    fn narrow(&self, other: &Range<T>) -> Range<T> {
264        Range::narrow(self, other)
265    }
266}