Skip to content

Commit c821bbc

Browse files
committed
rework universes big time, most tests pass
1 parent b2e3a56 commit c821bbc

25 files changed

+633
-419
lines changed

crates/formality-logic/src/env/query/extract_query_result.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,6 @@ fn close_over(
107107
let to_bound_variables: VarSubstitution = new_inference_variables
108108
.iter()
109109
.zip(&fresh_bound_variables)
110-
.upcasted()
111110
.collect();
112111

113112
let bound_data = QueryResultBoundData {

crates/formality-logic/src/env/query/querify.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ pub fn querify(
6060
let mut universe_counters: Map<Universe, VarIndex> = Map::default();
6161
let var_substitution: VarSubstitution = source_free_vars
6262
.iter()
63-
.map(|&source_free_var| {
63+
.map(|&source_free_var| -> (Variable, Variable) {
6464
(
6565
source_free_var,
6666
match source_free_var {

crates/formality-prove/src/prove.rs

Lines changed: 18 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,60 +1,59 @@
11
mod constraints;
2-
mod forall;
2+
mod env;
33
mod prove_after;
44
mod prove_apr;
55
mod prove_apr_via;
66
mod prove_eq;
77
mod prove_normalize;
88
mod prove_wc;
99
mod prove_wc_list;
10-
mod subst;
1110

1211
pub use constraints::Constraints;
13-
use formality_types::{
14-
cast::Upcast,
15-
collections::Set,
16-
grammar::{Binder, Wcs},
17-
set,
18-
visit::Visit,
19-
};
12+
use formality_types::{cast::Upcast, collections::Set, grammar::Wcs, set, visit::Visit};
2013
use tracing::Level;
2114

2215
use crate::program::Program;
2316

17+
pub use self::env::Env;
2418
use self::prove_wc_list::prove_wc_list;
2519

2620
/// Top-level entry point for proving things; other rules recurse to this one.
2721
pub fn prove(
2822
program: impl Upcast<Program>,
23+
env: impl Upcast<Env>,
2924
assumptions: impl Upcast<Wcs>,
3025
goal: impl Upcast<Wcs>,
31-
) -> Set<Binder<Constraints>> {
26+
) -> Set<(Env, Constraints)> {
3227
let program: Program = program.upcast();
28+
let env0: Env = env.upcast();
3329
let assumptions: Wcs = assumptions.upcast();
3430
let goal: Wcs = goal.upcast();
3531

3632
let span = tracing::span!(Level::DEBUG, "prove", ?goal, ?assumptions);
3733
let _guard = span.enter();
3834

3935
let term_in = (&assumptions, &goal);
40-
let fv_in = term_in.free_variables();
4136
if term_in.size() > program.max_size {
4237
tracing::debug!(
4338
"term has size {} which exceeds max size of {}",
4439
term_in.size(),
4540
program.max_size
4641
);
47-
return set![Binder::dummy(Constraints::default().ambiguous())];
42+
return set![(env0, Constraints::default().ambiguous())];
4843
}
4944

50-
let cs = prove_wc_list(program, assumptions, goal);
45+
env0.assert_encloses(term_in);
5146

52-
cs.assert_valid();
53-
cs.free_variables()
54-
.iter()
55-
.for_each(|fv| assert!(fv_in.contains(&fv)));
47+
let result_set = prove_wc_list(program, &env0, assumptions, goal);
5648

57-
tracing::debug!(?cs);
49+
result_set.iter().for_each(|(env1, constraints1)| {
50+
env1.assert_valid();
51+
env1.assert_valid_extension_of(&env0);
52+
env1.assert_encloses(&constraints1);
53+
constraints1.assert_valid();
54+
});
5855

59-
cs
56+
tracing::debug!(?result_set);
57+
58+
result_set
6059
}

crates/formality-prove/src/prove/constraints.rs

Lines changed: 75 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,12 @@ use formality_types::{
33
cast_impl,
44
derive_links::UpcastFrom,
55
fold::Fold,
6-
grammar::{Binder, InferenceVar, Parameter, Substitution, Variable},
6+
grammar::{Parameter, Substitution, Variable},
77
term::Term,
88
visit::Visit,
99
};
1010

11-
use super::subst::existential_substitution;
11+
use super::env::Env;
1212

1313
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
1414
pub struct Constraints<R: Term = ()> {
@@ -40,13 +40,13 @@ where
4040
{
4141
fn from_iter<T: IntoIterator<Item = (A, B)>>(iter: T) -> Self {
4242
let substitution = iter.into_iter().collect();
43-
let c = Constraints {
43+
let c2 = Constraints {
4444
substitution,
4545
known_true: true,
4646
result: (),
4747
};
48-
c.assert_valid();
49-
c
48+
c2.assert_valid();
49+
c2
5050
}
5151
}
5252

@@ -72,110 +72,88 @@ impl<R: Term> Constraints<R> {
7272
}
7373
}
7474

75-
pub fn map<S: Term>(self, op: impl FnOnce(R) -> S) -> Constraints<S> {
76-
let Constraints {
77-
result,
78-
known_true,
79-
substitution,
80-
} = self;
81-
let result = op(result);
75+
/// Given constraings from solving the subparts of `(A /\ B)`, yield combined constraints.
76+
///
77+
/// # Parameters
78+
///
79+
/// * `self` -- the constraints from solving `A`
80+
/// * `c2` -- the constraints from solving `B` (after applying substitution from `self` to `B`)
81+
pub fn seq<R2: Term>(&self, c2: impl Upcast<Constraints<R2>>) -> Constraints<R2>
82+
where
83+
R: CombineResults<R2>,
84+
{
85+
let c2: Constraints<R2> = c2.upcast();
86+
87+
self.assert_valid();
88+
c2.assert_valid();
89+
90+
// This substitution should have already been applied to produce
91+
// `c2`, therefore we don't expect any bindings for *our* variables.
92+
assert!(self
93+
.substitution
94+
.domain()
95+
.is_disjoint(&c2.substitution.domain()));
96+
97+
// Similarly, we don't expect any references to variables that we have
98+
// defined.
99+
assert!(self
100+
.substitution
101+
.domain()
102+
.iter()
103+
.all(|v| !occurs_in(v, &c2.substitution)));
104+
105+
// Apply c2's substitution to our substitution (since it may have bound
106+
// existential variables that we reference)
107+
let c1_substitution = c2.substitution.apply(&self.substitution);
108+
82109
Constraints {
83-
known_true,
84-
substitution,
85-
result,
110+
known_true: self.known_true && c2.known_true,
111+
result: R::combine(&self.result, c2.result),
112+
substitution: c1_substitution.into_iter().chain(c2.substitution).collect(),
86113
}
87114
}
88115

89-
pub fn split_result(self) -> (R, Constraints) {
90-
let Constraints {
91-
result,
92-
known_true,
93-
substitution,
94-
} = self;
95-
(
96-
result,
97-
Constraints {
98-
known_true,
99-
substitution,
100-
result: (),
101-
},
102-
)
103-
}
104-
}
116+
pub fn assert_valid_in(&self, env: &Env) {
117+
self.assert_valid();
105118

106-
pub fn instantiate_and_apply_constraints<T: Term, R: Term>(
107-
c: Binder<Constraints<R>>,
108-
term: T,
109-
) -> (Vec<InferenceVar>, Constraints<R>, T) {
110-
let existentials = existential_substitution(&c, &term);
111-
let c = c.instantiate_with(&existentials).unwrap();
112-
let term = c.substitution().apply(&term);
113-
(existentials, c, term)
114-
}
119+
// Each variable `x` is only bound to a term of strictly lower universe.
120+
// This implies that `x` does not appear in `p`.
121+
for (x, p) in self.substitution.iter() {
122+
let fvs = p.free_variables();
123+
fvs.iter()
124+
.for_each(|fv| assert!(env.universe(fv) < env.universe(x)));
125+
}
126+
}
115127

116-
pub fn merge_constraints<R0: Term, R1: Term>(
117-
existentials: impl Upcast<Vec<Variable>>,
118-
c0: impl Upcast<Constraints<R0>>,
119-
c1: Binder<Constraints<R1>>,
120-
) -> Binder<Constraints<R1>>
121-
where
122-
R0: CombineResults<R1>,
123-
{
124-
let c0: Constraints<R0> = c0.upcast();
125-
c0.assert_valid();
126-
127-
let (c1_bound_vars, c1) = c1.open();
128-
c1.assert_valid();
129-
130-
assert!(c0
131-
.substitution
132-
.domain()
133-
.is_disjoint(&c1.substitution.domain()));
134-
assert!(!c0
135-
.substitution
136-
.domain()
137-
.iter()
138-
.any(|v| occurs_in(v, &c1.substitution)));
139-
140-
let existentials: Vec<Variable> = existentials.upcast();
141-
142-
let c0 = c1.substitution.apply(&c0);
143-
144-
// Drop any bindings `X := P` from the subst that appear in the `variables` set;
145-
// those are existentials that we temporarily introduced and no longer need.
146-
let substitution = c0
147-
.substitution
148-
.into_iter()
149-
.chain(c1.substitution)
150-
.filter(|(v, _)| !existentials.contains(&v.upcast()))
151-
.collect();
128+
pub fn pop_subst<V>(mut self, mut env: Env, v: &[V]) -> (Env, Constraints<R>)
129+
where
130+
V: Upcast<Variable> + Copy,
131+
{
132+
self.assert_valid_in(&env);
152133

153-
let known_true = c0.known_true && c1.known_true;
134+
if v.len() == 0 {
135+
return (env, self);
136+
}
154137

155-
let result = R0::combine(c0.result, c1.result);
138+
let vars = env.pop_vars(v);
139+
self.substitution -= vars;
156140

157-
Binder::mentioned(
158-
(c1_bound_vars, existentials),
159-
Constraints {
160-
known_true,
161-
substitution,
162-
result,
163-
},
164-
)
141+
(env, self)
142+
}
165143
}
166144

167145
impl<R: Term> Fold for Constraints<R> {
168146
fn substitute(&self, substitution_fn: formality_types::fold::SubstitutionFn<'_>) -> Self {
169-
let c = Constraints {
147+
let c2 = Constraints {
170148
known_true: self.known_true,
171149
substitution: self.substitution.substitute(substitution_fn),
172150
result: self.result.substitute(substitution_fn),
173151
};
174152

175153
// not all substitutions preserve the constraint set invariant
176-
c.assert_valid();
154+
c2.assert_valid();
177155

178-
c
156+
c2
179157
}
180158
}
181159

@@ -244,33 +222,27 @@ pub fn is_valid_binding(v: impl Upcast<Variable>, t: &impl Visit) -> bool {
244222
.all(|fv| fv != v && fv.max_universe() <= v_universe)
245223
}
246224

247-
pub fn constrain(v: impl Upcast<InferenceVar>, p: impl Upcast<Parameter>) -> Binder<Constraints> {
248-
let v: InferenceVar = v.upcast();
249-
let p: Parameter = p.upcast();
250-
Binder::dummy((v, p).upcast())
251-
}
252-
253-
pub fn no_constraints<R: Term>(result: R) -> Binder<Constraints<R>> {
254-
Binder::dummy(Constraints {
255-
result,
225+
pub fn no_constraints() -> Constraints {
226+
Constraints {
227+
result: (),
256228
known_true: true,
257229
substitution: Substitution::default(),
258-
})
230+
}
259231
}
260232

261233
pub trait CombineResults<R> {
262-
fn combine(r0: Self, r1: R) -> R;
234+
fn combine(r0: &Self, r1: R) -> R;
263235
}
264236

265237
impl<R> CombineResults<R> for () {
266-
fn combine((): (), r1: R) -> R {
238+
fn combine((): &(), r1: R) -> R {
267239
r1
268240
}
269241
}
270242

271243
impl CombineResults<Vec<Parameter>> for Parameter {
272-
fn combine(r0: Self, mut r1: Vec<Parameter>) -> Vec<Parameter> {
273-
r1.push(r0);
244+
fn combine(r0: &Self, mut r1: Vec<Parameter>) -> Vec<Parameter> {
245+
r1.push(r0.clone());
274246
r1
275247
}
276248
}

0 commit comments

Comments
 (0)