Skip to content

Commit eeeddde

Browse files
committed
wip wip
1 parent ae30d7b commit eeeddde

26 files changed

+511
-102
lines changed

crates/formality-logic/src/env.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ impl Env {
110110
});
111111
InferenceVar {
112112
var_index: VarIndex { index },
113+
universe: universe,
113114
kind,
114115
}
115116
}
@@ -121,6 +122,7 @@ impl Env {
121122
.zip(0..)
122123
.map(|(id, index)| InferenceVar {
123124
var_index: VarIndex { index },
125+
universe: id.universe,
124126
kind: id.kind,
125127
})
126128
.collect()
@@ -307,6 +309,7 @@ impl Env {
307309
.flat_map(|(data, index)| {
308310
self.inference_var_relations(InferenceVar {
309311
var_index: VarIndex { index },
312+
universe: data.universe,
310313
kind: data.kind,
311314
})
312315
})

crates/formality-prove/src/prove.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ mod prove_after;
44
mod prove_apr;
55
mod prove_apr_via;
66
mod prove_eq;
7+
mod prove_normalize;
78
mod prove_wc;
89
mod prove_wc_list;
910
mod subst;

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

Lines changed: 143 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,20 @@ use formality_types::{
44
derive_links::UpcastFrom,
55
fold::Fold,
66
grammar::{Binder, InferenceVar, Parameter, Substitution, Variable},
7+
term::Term,
78
visit::Visit,
89
};
910

11+
use super::subst::existential_substitution;
12+
1013
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
11-
pub struct Constraints {
14+
pub struct Constraints<R: Term = ()> {
15+
result: R,
1216
known_true: bool,
1317
substitution: Substitution,
1418
}
1519

16-
cast_impl!(Constraints);
20+
cast_impl!(impl(R: Term) Constraints<R>);
1721

1822
impl<A, B> UpcastFrom<(A, B)> for Constraints
1923
where
@@ -24,38 +28,100 @@ where
2428
Constraints {
2529
substitution: term.upcast(),
2630
known_true: true,
31+
result: (),
2732
}
2833
}
2934
}
3035

36+
impl<A, B> FromIterator<(A, B)> for Constraints
37+
where
38+
A: Upcast<Variable>,
39+
B: Upcast<Parameter>,
40+
{
41+
fn from_iter<T: IntoIterator<Item = (A, B)>>(iter: T) -> Self {
42+
let substitution = iter.into_iter().collect();
43+
let c = Constraints {
44+
substitution,
45+
known_true: true,
46+
result: (),
47+
};
48+
c.assert_valid();
49+
c
50+
}
51+
}
52+
3153
impl Default for Constraints {
3254
fn default() -> Self {
3355
Self {
56+
result: (),
3457
known_true: true,
3558
substitution: Default::default(),
3659
}
3760
}
3861
}
3962

40-
impl Constraints {
63+
impl<R: Term> Constraints<R> {
4164
pub fn substitution(&self) -> &Substitution {
4265
&self.substitution
4366
}
4467

45-
pub fn ambiguous(self) -> Constraints {
68+
pub fn ambiguous(self) -> Constraints<R> {
4669
Self {
4770
known_true: false,
4871
..self
4972
}
5073
}
74+
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);
82+
Constraints {
83+
known_true,
84+
substitution,
85+
result,
86+
}
87+
}
88+
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+
}
51104
}
52105

53-
pub fn merge_constraints(
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+
}
115+
116+
pub fn merge_constraints<R0: Term, R1: Term>(
54117
existentials: impl Upcast<Vec<Variable>>,
55-
c0: impl Upcast<Constraints>,
56-
c1: Binder<Constraints>,
57-
) -> Binder<Constraints> {
58-
let c0: Constraints = c0.upcast();
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();
59125
c0.assert_valid();
60126

61127
let (c1_bound_vars, c1) = c1.open();
@@ -85,20 +151,25 @@ pub fn merge_constraints(
85151
.collect();
86152

87153
let known_true = c0.known_true && c1.known_true;
154+
155+
let result = R0::combine(c0.result, c1.result);
156+
88157
Binder::mentioned(
89158
(c1_bound_vars, existentials),
90159
Constraints {
91160
known_true,
92161
substitution,
162+
result,
93163
},
94164
)
95165
}
96166

97-
impl Fold for Constraints {
167+
impl<R: Term> Fold for Constraints<R> {
98168
fn substitute(&self, substitution_fn: formality_types::fold::SubstitutionFn<'_>) -> Self {
99169
let c = Constraints {
100170
known_true: self.known_true,
101171
substitution: self.substitution.substitute(substitution_fn),
172+
result: self.result.substitute(substitution_fn),
102173
};
103174

104175
// not all substitutions preserve the constraint set invariant
@@ -108,29 +179,50 @@ impl Fold for Constraints {
108179
}
109180
}
110181

111-
impl Visit for Constraints {
182+
impl<R: Term> Visit for Constraints<R> {
112183
fn free_variables(&self) -> Vec<Variable> {
113184
let Constraints {
114185
known_true: _,
115186
substitution,
187+
result,
116188
} = self;
117-
substitution.free_variables()
189+
190+
substitution
191+
.free_variables()
192+
.into_iter()
193+
.chain(result.free_variables())
194+
.collect()
118195
}
119196

120197
fn size(&self) -> usize {
121198
let Constraints {
122199
known_true: _,
123200
substitution,
201+
result,
124202
} = self;
125-
substitution.size()
203+
substitution.size() + result.size()
126204
}
127205

128206
fn assert_valid(&self) {
129-
let domain = self.substitution.domain();
130-
let range = self.substitution.range();
207+
let Constraints {
208+
known_true: _,
209+
substitution,
210+
result,
211+
} = self;
212+
213+
let domain = substitution.domain();
214+
215+
for &v in &domain {
216+
assert!(v.is_free());
217+
assert!(is_valid_binding(v, &substitution[v]));
218+
}
219+
220+
let range = substitution.range();
131221
range
132222
.iter()
133223
.for_each(|t| assert!(domain.iter().all(|&v| !occurs_in(v, t))));
224+
225+
result.assert_valid();
134226
}
135227
}
136228

@@ -139,12 +231,46 @@ pub fn occurs_in(v: impl Upcast<Variable>, t: &impl Visit) -> bool {
139231
t.free_variables().contains(&v)
140232
}
141233

234+
/// True if `t` would be a valid binding for `v`, meaning...
235+
/// * `v` does not appear in `t`; and,
236+
/// * all free variables in `t` are within the universe of `v`
237+
pub fn is_valid_binding(v: impl Upcast<Variable>, t: &impl Visit) -> bool {
238+
let v: Variable = v.upcast();
239+
assert!(v.is_free());
240+
241+
let v_universe = v.max_universe();
242+
t.free_variables()
243+
.into_iter()
244+
.all(|fv| fv != v && fv.max_universe() <= v_universe)
245+
}
246+
142247
pub fn constrain(v: impl Upcast<InferenceVar>, p: impl Upcast<Parameter>) -> Binder<Constraints> {
143248
let v: InferenceVar = v.upcast();
144249
let p: Parameter = p.upcast();
145250
Binder::dummy((v, p).upcast())
146251
}
147252

148-
pub fn no_constraints() -> Binder<Constraints> {
149-
Binder::dummy(().upcast())
253+
pub fn no_constraints<R: Term>(result: R) -> Binder<Constraints<R>> {
254+
Binder::dummy(Constraints {
255+
result,
256+
known_true: true,
257+
substitution: Substitution::default(),
258+
})
259+
}
260+
261+
pub trait CombineResults<R> {
262+
fn combine(r0: Self, r1: R) -> R;
263+
}
264+
265+
impl<R> CombineResults<R> for () {
266+
fn combine((): (), r1: R) -> R {
267+
r1
268+
}
269+
}
270+
271+
impl CombineResults<Vec<Parameter>> for Parameter {
272+
fn combine(r0: Self, mut r1: Vec<Parameter>) -> Vec<Parameter> {
273+
r1.push(r0);
274+
r1
275+
}
150276
}

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

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,13 @@ use formality_types::{
55

66
use crate::{
77
program::Program,
8-
prove::{constraints::merge_constraints, prove},
8+
prove::{
9+
constraints::{instantiate_and_apply_constraints, merge_constraints},
10+
prove,
11+
},
912
};
1013

11-
use super::{constraints::Constraints, subst::existential_substitution};
14+
use super::constraints::Constraints;
1215

1316
judgment_fn! {
1417
pub fn prove_after(
@@ -18,10 +21,7 @@ judgment_fn! {
1821
goal: Wcs,
1922
) => Binder<Constraints> {
2023
(
21-
(let existentials = existential_substitution(&c1, (&assumptions, &goal)))
22-
(let c1 = c1.instantiate_with(&existentials).unwrap())
23-
(let assumptions = c1.substitution().apply(&assumptions))
24-
(let goal = c1.substitution().apply(&goal))
24+
(let (existentials, c1, (assumptions, goal)) = instantiate_and_apply_constraints(c1, (assumptions, goal)))
2525
(prove(program, assumptions, goal) => c2)
2626
--- ("prove_after")
2727
(prove_after(program, c1, assumptions, goal) => merge_constraints(&existentials, &c1, c2))

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

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,10 @@ use formality_types::{
66
use crate::{
77
program::Program,
88
prove::{
9-
constraints::{merge_constraints, Constraints},
9+
constraints::{merge_constraints, no_constraints, Constraints},
10+
prove,
1011
prove_after::prove_after,
11-
prove_eq::prove_parameters_eq,
12+
prove_eq::all_eq,
1213
subst::existential_substitution,
1314
},
1415
};
@@ -21,12 +22,21 @@ judgment_fn! {
2122
goal: APR,
2223
) => Binder<Constraints> {
2324
(
24-
(let (skel_c, parameters_c) = clause.debone())
25+
(let (skel_c, parameters_c) = predicate.debone())
2526
(let (skel_g, parameters_g) = goal.debone())
2627
(if skel_c == skel_g)
27-
(prove_parameters_eq(program, assumptions, parameters_c, parameters_g) => c)
28-
----------------------------- ("axiom")
29-
(prove_apr_via(program, assumptions, WcData::Atomic(clause), goal) => c)
28+
(prove(program, assumptions, all_eq(parameters_c, parameters_g)) => c)
29+
----------------------------- ("predicate-congruence-axiom")
30+
(prove_apr_via(program, assumptions, APR::AtomicPredicate(predicate), goal) => c)
31+
)
32+
33+
(
34+
(let (skel_c, parameters_c) = relation.debone())
35+
(let (skel_g, parameters_g) = goal.debone())
36+
(if skel_c == skel_g)
37+
(if parameters_c == parameters_g) // for relations, we require 100% match
38+
----------------------------- ("relation-axiom")
39+
(prove_apr_via(_program, _assumptions, APR::AtomicRelation(relation), goal) => no_constraints(()))
3040
)
3141

3242
(
@@ -43,5 +53,5 @@ judgment_fn! {
4353
----------------------------- ("implies")
4454
(prove_apr_via(program, assumptions, WcData::Implies(wc_condition, wc_consequence), goal) => c2)
4555
)
46-
}
56+
}
4757
}

0 commit comments

Comments
 (0)