pub struct FlatConstraint<T: Types> {
pub binders: Vec<(T::Var, Sort<T>)>,
pub assumptions: FxIndexSet<Pred<T>>,
pub head: Pred<T>,
pub tag: Option<T::Tag>,
}Fields§
§binders: Vec<(T::Var, Sort<T>)>All of the binders that come before the head.
NOTE: There should be no duplicates among the binders which are used (so e.g. UNDERSCORE appearing multiple times is OK).
assumptions: FxIndexSet<Pred<T>>All of the assumptions (i.e. a flattened conjunction of predicates from all of the binders)
head: Pred<T>§tag: Option<T::Tag>Implementations§
Source§impl<T: Types> FlatConstraint<T>
impl<T: Types> FlatConstraint<T>
Sourcepub fn remove_binders(
&self,
vars: &HashSet<T::Var>,
) -> (Vec<ConstDecl<T>>, FlatConstraint<T>)
pub fn remove_binders( &self, vars: &HashSet<T::Var>, ) -> (Vec<ConstDecl<T>>, FlatConstraint<T>)
Removes any binder corresponding to a given var. Returns the new constraint along with the removed binders and their sorts.
NOTE: Assumes that all binders are unique and therefore there are no name clashes.
pub fn add_assumption(&mut self, assumption: Pred<T>)
pub fn preconditions(&self) -> FxIndexSet<Pred<T>>
Sourcepub fn wkvars_and_constrs(
&self,
) -> Vec<(WKVar<T>, FlatConstraint<T>, Vec<FlatConstraint<T>>)>
pub fn wkvars_and_constrs( &self, ) -> Vec<(WKVar<T>, FlatConstraint<T>, Vec<FlatConstraint<T>>)>
Each element of the output is a wkvar, the constraint it corresponds to, and the other constraints which must also hold.
We essentially “decompose” each assumption which contains a wkvar in order to transform the constraint into one in which that wkvar is exposed.
These decompositions are of two forms.
- Hoisting existentials to the top level.
- Splitting disjuncts using the below property. When we split a disjunct, we generate other constraints. A more sophisticated analysis might try and solve multiple constraints simultaneously; if we were to do this, we would probably want to change how this algorithm works to avoid redundancy, e.g. by instead of generating ((wkvar, constr, other_constrs) outputs generating (all_constrs) outputs and letting consumers choose which wkvars to solve in each constr.
(p || q) => c
==
(p => c) && (q => c)Trait Implementations§
Source§impl<T: Types> Clone for FlatConstraint<T>
impl<T: Types> Clone for FlatConstraint<T>
Auto Trait Implementations§
impl<T> Freeze for FlatConstraint<T>
impl<T> RefUnwindSafe for FlatConstraint<T>where
<T as Types>::KVar: RefUnwindSafe,
<T as Types>::Tag: RefUnwindSafe,
<T as Types>::Var: RefUnwindSafe,
<T as Types>::Real: RefUnwindSafe,
<T as Types>::String: RefUnwindSafe,
<T as Types>::Sort: RefUnwindSafe,
impl<T> Send for FlatConstraint<T>
impl<T> Sync for FlatConstraint<T>
impl<T> Unpin for FlatConstraint<T>
impl<T> UnwindSafe for FlatConstraint<T>where
<T as Types>::KVar: UnwindSafe,
<T as Types>::Tag: UnwindSafe,
<T as Types>::Var: UnwindSafe,
<T as Types>::Real: UnwindSafe,
<T as Types>::String: UnwindSafe,
<T as Types>::Sort: UnwindSafe,
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more