3 use crate::infer
::InferenceTable
;
4 use chalk_ir
::interner
::Interner
;
5 use chalk_ir
::visit
::{ControlFlow, SuperVisit, Visit, Visitor}
;
9 /// "Truncation" (called "abstraction" in the papers referenced below)
10 /// refers to the act of modifying a goal or answer that has become
11 /// too large in order to guarantee termination.
13 /// Currently we don't perform truncation (but it might me readded later).
17 /// - Terminating Evaluation of Logic Programs with Finite Three-Valued Models
18 /// - Riguzzi and Swift; ACM Transactions on Computational Logic 2013
19 /// - Radial Restraint
20 /// - Grosof and Swift; 2013
21 pub fn needs_truncation
<I
: Interner
>(
23 infer
: &mut InferenceTable
<I
>,
27 let mut visitor
= TySizeVisitor
::new(interner
, infer
);
28 value
.visit_with(&mut visitor
, DebruijnIndex
::INNERMOST
);
30 visitor
.max_size
> max_size
33 struct TySizeVisitor
<'infer
, 'i
, I
: Interner
> {
35 infer
: &'infer
mut InferenceTable
<I
>,
41 impl<'infer
, 'i
, I
: Interner
> TySizeVisitor
<'infer
, 'i
, I
> {
42 fn new(interner
: &'i I
, infer
: &'infer
mut InferenceTable
<I
>) -> Self {
53 impl<'infer
, 'i
, I
: Interner
> Visitor
<'i
, I
> for TySizeVisitor
<'infer
, 'i
, I
> {
56 fn as_dyn(&mut self) -> &mut dyn Visitor
<'i
, I
, BreakTy
= Self::BreakTy
> {
60 fn visit_ty(&mut self, ty
: &Ty
<I
>, outer_binder
: DebruijnIndex
) -> ControlFlow
<()> {
61 if let Some(normalized_ty
) = self.infer
.normalize_ty_shallow(self.interner
, ty
) {
62 normalized_ty
.visit_with(self, outer_binder
);
63 return ControlFlow
::CONTINUE
;
67 self.max_size
= max(self.size
, self.max_size
);
70 ty
.super_visit_with(self, outer_binder
);
73 // When we get back to the first invocation, clear the counters.
74 // We process each outermost type independently.
81 fn interner(&self) -> &'i I
{
89 use chalk_integration
::{arg, ty}
;
93 use chalk_integration
::interner
::ChalkIr
;
94 let interner
= &ChalkIr
;
95 let mut table
= InferenceTable
::<chalk_integration
::interner
::ChalkIr
>::new();
96 let _u1
= table
.new_universe();
98 // Vec<Vec<Vec<Vec<T>>>>
99 let ty0
= ty
!(apply (item
0)
105 let mut visitor
= TySizeVisitor
::new(interner
, &mut table
);
106 ty0
.visit_with(&mut visitor
, DebruijnIndex
::INNERMOST
);
107 assert
!(visitor
.max_size
== 5);
111 fn multiple_types() {
112 use chalk_integration
::interner
::ChalkIr
;
113 let interner
= &ChalkIr
;
114 let mut table
= InferenceTable
::<chalk_integration
::interner
::ChalkIr
>::new();
115 let _u1
= table
.new_universe();
117 // Vec<Vec<Vec<Vec<T>>>>
118 let ty0
= ty
!(apply (item
0)
124 let ty1
= ty
!(apply (item
0)
129 let mut visitor
= TySizeVisitor
::new(interner
, &mut table
);
130 vec
![&ty0
, &ty1
].visit_with(&mut visitor
, DebruijnIndex
::INNERMOST
);
131 assert
!(visitor
.max_size
== 5);