Skip to content

Commit bdeac66

Browse files
committed
introduce prove function
add postcondition checking
1 parent f4330df commit bdeac66

File tree

7 files changed

+47
-15
lines changed

7 files changed

+47
-15
lines changed

crates/formality-prove/src/prove.rs

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,34 @@ mod prove_wc_list;
99
mod subst;
1010

1111
pub use constraints::Constraints;
12-
pub use prove_wc_list::prove_wc_list;
12+
use formality_types::{
13+
cast::Upcast,
14+
collections::Set,
15+
grammar::{Binder, Wcs},
16+
visit::Visit,
17+
};
18+
19+
use crate::program::Program;
20+
21+
use self::prove_wc_list::prove_wc_list;
22+
23+
/// Top-level entry point for proving things; other rules recurse to this one.
24+
pub fn prove(
25+
program: impl Upcast<Program>,
26+
assumptions: impl Upcast<Wcs>,
27+
goal: impl Upcast<Wcs>,
28+
) -> Set<Binder<Constraints>> {
29+
let program: Program = program.upcast();
30+
let assumptions: Wcs = assumptions.upcast();
31+
let goal: Wcs = goal.upcast();
32+
33+
let fv_in = (&assumptions, &goal).free_variables();
34+
35+
let cs = prove_wc_list(program, assumptions, goal);
36+
37+
cs.free_variables()
38+
.iter()
39+
.for_each(|fv| assert!(fv_in.contains(&fv)));
40+
41+
cs
42+
}

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

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

66
use crate::{
77
program::Program,
8-
prove::{constraints::merge_constraints, prove_wc_list::prove_wc_list},
8+
prove::{constraints::merge_constraints, prove, prove_wc_list::prove_wc_list},
99
};
1010

1111
use super::{constraints::Constraints, subst::existential_substitution};
@@ -22,7 +22,7 @@ judgment_fn! {
2222
(let c1 = c1.instantiate_with(&existentials).unwrap())
2323
(let assumptions = c1.substitution().apply(&assumptions))
2424
(let goal = c1.substitution().apply(&goal))
25-
(prove_wc_list(program, assumptions, goal) => c2)
25+
(prove(program, assumptions, goal) => c2)
2626
--- ("prove_after")
2727
(prove_after(program, c1, assumptions, goal) => merge_constraints(&existentials, &c1, c2))
2828
)

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use crate::{
77
program::Program,
88
prove::{
99
constraints::merge_constraints,
10+
prove,
1011
prove_after::prove_after,
1112
prove_apr_via::prove_apr_via,
1213
prove_eq::{all_eq, prove_ty_eq},
@@ -36,7 +37,7 @@ judgment_fn! {
3637
(let i = i.binder.instantiate_with(&subst).unwrap())
3738
(let t = program.trait_decl(&i.trait_ref.trait_id).binder.instantiate_with(&i.trait_ref.parameters).unwrap())
3839
(let assumptions_c = (&assumptions, trait_ref.is_implemented()))
39-
(prove_wc_list(&program, &assumptions_c, all_eq(&trait_ref.parameters, &i.trait_ref.parameters)) => c1)
40+
(prove(&program, &assumptions_c, all_eq(&trait_ref.parameters, &i.trait_ref.parameters)) => c1)
4041
(prove_after(&program, c1, &assumptions_c, (&i.where_clause, &t.where_clause)) => c2)
4142
----------------------------- ("impl")
4243
(prove_apr(program, assumptions, AtomicPredicate::IsImplemented(trait_ref)) => merge_constraints(&subst, (), c2))

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ use crate::{
1212
program::Program,
1313
prove::{
1414
constraints::{constrain, merge_constraints, no_constraints, occurs_in},
15+
prove,
1516
subst::existential_substitution,
1617
},
1718
};
@@ -44,7 +45,7 @@ pub fn prove_parameters_eq(
4445
let program = program.upcast();
4546
let assumptions = assumptions.upcast();
4647
let goals = all_eq(a, b);
47-
prove_wc_list(program, assumptions, goals)
48+
prove(program, assumptions, goals)
4849
}
4950

5051
judgment_fn! {
@@ -112,7 +113,7 @@ judgment_fn! {
112113
// Normalizing to a variable or alias: not productive
113114
assumptions.clone()
114115
})
115-
(prove_wc_list(&program, &assumptions1, (
116+
(prove(&program, &assumptions1, (
116117
all_eq(&a.parameters, &decl.alias.parameters),
117118
eq(&b, &decl.ty),
118119
decl.where_clause,

crates/formality-prove/src/test.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use formality_types::{
66

77
use crate::{
88
program::Program,
9-
prove::{prove_wc_list, Constraints},
9+
prove::{prove, Constraints},
1010
};
1111

1212
mod eq_partial_eq;
@@ -22,5 +22,5 @@ mod universes;
2222
fn test_prove(program: Program, t: Binder<(Wcs, Wcs)>) -> Set<Binder<Constraints>> {
2323
let (assumptions, goals) =
2424
t.instantiate(|kind, var_index| InferenceVar { kind, var_index }.upcast());
25-
prove_wc_list(program, assumptions, goals)
25+
prove(program, assumptions, goals)
2626
}

crates/formality-prove/src/test/eq_partial_eq.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use formality_types::{
55
parse::term,
66
};
77

8-
use crate::{program::Program, prove::prove_wc_list};
8+
use crate::{program::Program, prove::prove};
99

1010
/// Simple example program consisting only of two trait declarations.
1111
fn program() -> Program {
@@ -25,7 +25,7 @@ fn program() -> Program {
2525
fn eq_implies_partial_eq() {
2626
let assumptions: Wcs = Wcs::t();
2727
let goal: Wc = term("for<ty T> if {is_implemented(Eq(T))} is_implemented(PartialEq(T))");
28-
let constraints = prove_wc_list(program(), assumptions, goal);
28+
let constraints = prove(program(), assumptions, goal);
2929
expect![[r#"
3030
{
3131
<> Constraints { known_true: true, substitution: Substitution { map: {} } },
@@ -38,7 +38,7 @@ fn eq_implies_partial_eq() {
3838
fn not_partial_eq_implies_eq() {
3939
let assumptions: Wcs = Wcs::t();
4040
let goal: Wc = term("for<ty T> if {is_implemented(PartialEq(T))} is_implemented(Eq(T))");
41-
let constraints = prove_wc_list(program(), assumptions, goal);
41+
let constraints = prove(program(), assumptions, goal);
4242
expect![[r#"
4343
{}
4444
"#]]
@@ -49,7 +49,7 @@ fn not_partial_eq_implies_eq() {
4949
fn placeholders_not_eq() {
5050
let assumptions: Wcs = Wcs::t();
5151
let goal: Wc = term("for<ty T, ty U> if {is_implemented(Eq(T))} is_implemented(PartialEq(U))");
52-
let constraints = prove_wc_list(program(), assumptions, goal);
52+
let constraints = prove(program(), assumptions, goal);
5353
expect![[r#"
5454
{}
5555
"#]]

crates/formality-prove/src/test/simple_impl.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use formality_types::{
55
parse::term,
66
};
77

8-
use crate::{program::Program, prove::prove_wc_list};
8+
use crate::{program::Program, prove::prove};
99

1010
/// Simple example program consisting only of two trait declarations.
1111
fn program() -> Program {
@@ -25,7 +25,7 @@ fn program() -> Program {
2525
fn vec_u32_debug() {
2626
let assumptions: Wcs = Wcs::t();
2727
let goal: Wc = term("is_implemented(Debug(Vec<u32>))");
28-
let constraints = prove_wc_list(program(), assumptions, goal);
28+
let constraints = prove(program(), assumptions, goal);
2929
expect![[r#"
3030
{
3131
<> Constraints { known_true: true, substitution: Substitution { map: {} } },
@@ -38,7 +38,7 @@ fn vec_u32_debug() {
3838
fn vec_vec_u32_debug() {
3939
let assumptions: Wcs = Wcs::t();
4040
let goal: Wc = term("is_implemented(Debug(Vec<Vec<u32>>))");
41-
let constraints = prove_wc_list(program(), assumptions, goal);
41+
let constraints = prove(program(), assumptions, goal);
4242
expect![[r#"
4343
{
4444
<> Constraints { known_true: true, substitution: Substitution { map: {} } },

0 commit comments

Comments
 (0)