Skip to content

Commit 6ae9ccd

Browse files
committed
convert formality-check and friends
(untested)
1 parent 819a4c3 commit 6ae9ccd

File tree

17 files changed

+323
-581
lines changed

17 files changed

+323
-581
lines changed

Cargo.lock

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/formality-check/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ formality-types = { path = "../formality-types" }
1010
formality-macros = { path = "../formality-macros" }
1111
formality-core = { path = "../formality-core" }
1212
formality-rust = { path = "../formality-rust" }
13+
formality-prove = { path = "../formality-prove" }
1314
tracing = "0.1"
1415
contracts = "0.6.3"
1516
anyhow = "1.0.66"

crates/formality-check/src/adts.rs

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,10 @@
1-
use formality_decl::grammar::{Adt, AdtBoundData, AdtVariant, Field};
2-
use formality_types::{
3-
cast::To,
4-
grammar::{Fallible, Hypothesis},
5-
};
1+
use formality_prove::Env;
2+
use formality_rust::grammar::{Adt, AdtBoundData, Field, Variant};
3+
use formality_types::grammar::Fallible;
64

75
impl super::Check<'_> {
86
pub(super) fn check_adt(&self, adt: &Adt) -> Fallible<()> {
9-
let Adt {
10-
kind: _,
11-
id: _,
12-
binder,
13-
} = adt;
7+
let Adt { id: _, binder } = adt;
148

159
let mut env = Env::default();
1610

@@ -19,15 +13,13 @@ impl super::Check<'_> {
1913
variants,
2014
} = env.instantiate_universally(binder);
2115

22-
let assumptions: Vec<Hypothesis> = where_clauses.to();
23-
24-
self.prove_where_clauses_well_formed(&env, &assumptions, &where_clauses)?;
16+
self.prove_where_clauses_well_formed(&env, &where_clauses, &where_clauses)?;
2517

2618
// FIXME: check names are unique or integers from 0..n
2719

28-
for AdtVariant { name: _, fields } in &variants {
20+
for Variant { name: _, fields } in &variants {
2921
for Field { name: _, ty } in fields {
30-
self.prove_goal(&env, &assumptions, ty.well_formed())?;
22+
self.prove_goal(&env, &where_clauses, ty.well_formed())?;
3123
}
3224
}
3325

crates/formality-check/src/coherence.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use anyhow::bail;
2-
use formality_decl::grammar::{Crate, TraitImpl};
2+
use formality_rust::grammar::{Crate, TraitImpl};
33
use formality_types::{cast::Downcasted, grammar::Fallible};
44
use itertools::Itertools;
55

crates/formality-check/src/fns.rs

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
1-
use formality_decl::grammar::{Fn, FnBoundData};
2-
use formality_logic::Env;
3-
use formality_types::{
4-
cast::Upcast,
5-
grammar::{Fallible, Hypothesis},
6-
};
1+
use formality_prove::Env;
2+
use formality_rust::grammar::{Fn, FnBoundData, WhereClause};
3+
use formality_types::{cast::Upcast, grammar::Fallible};
74

85
use crate::Check;
96

@@ -15,7 +12,7 @@ impl Check<'_> {
1512
pub(crate) fn check_fn(
1613
&self,
1714
in_env: &Env,
18-
in_assumptions: &[Hypothesis],
15+
in_assumptions: &[WhereClause],
1916
f: &Fn,
2017
) -> Fallible<()> {
2118
let mut env = in_env.clone();
@@ -26,9 +23,10 @@ impl Check<'_> {
2623
input_tys,
2724
output_ty,
2825
where_clauses,
26+
body: _,
2927
} = env.instantiate_universally(binder);
3028

31-
let assumptions: Vec<Hypothesis> = (in_assumptions, &where_clauses).upcast();
29+
let assumptions: Vec<WhereClause> = (in_assumptions, &where_clauses).upcast();
3230

3331
self.prove_where_clauses_well_formed(&env, &assumptions, &where_clauses)?;
3432

crates/formality-check/src/impls.rs

Lines changed: 27 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
use anyhow::bail;
22
use contracts::requires;
33
use fn_error_context::context;
4-
use formality_decl::grammar::{
4+
use formality_prove::Env;
5+
use formality_rust::grammar::{
56
AssociatedTy, AssociatedTyBoundData, AssociatedTyValue, AssociatedTyValueBoundData, Fn,
6-
FnBoundData, ImplItem, TraitBoundData, TraitImpl, TraitImplBoundData, TraitItem,
7+
FnBoundData, ImplItem, TraitBoundData, TraitImpl, TraitImplBoundData, TraitItem, WhereClause,
78
};
8-
use formality_logic::Env;
99
use formality_types::{
10-
cast::{Downcasted, To},
11-
grammar::{Binder, Fallible, Goal, Hypothesis, Substitution},
10+
cast::Downcasted,
11+
grammar::{AtomicRelation, Binder, Fallible, Substitution, Wcs},
1212
term::Term,
1313
visit::Visit,
1414
};
@@ -21,16 +21,18 @@ impl super::Check<'_> {
2121
let mut env = Env::default();
2222

2323
let TraitImplBoundData {
24-
trait_ref,
24+
trait_id,
25+
self_ty,
26+
trait_parameters,
2527
where_clauses,
2628
impl_items,
2729
} = env.instantiate_universally(binder);
2830

29-
let assumptions: Vec<Hypothesis> = where_clauses.to();
31+
let trait_ref = trait_id.with(self_ty, trait_parameters);
3032

31-
self.prove_where_clauses_well_formed(&env, &assumptions, &where_clauses)?;
33+
self.prove_where_clauses_well_formed(&env, &where_clauses, &where_clauses)?;
3234

33-
self.prove_goal(&env, &assumptions, trait_ref.is_implemented())?;
35+
self.prove_goal(&env, &where_clauses, trait_ref.is_implemented())?;
3436

3537
let trait_decl = self.program.trait_named(&trait_ref.trait_id)?;
3638
let TraitBoundData {
@@ -39,7 +41,7 @@ impl super::Check<'_> {
3941
} = trait_decl.binder.instantiate_with(&trait_ref.parameters)?;
4042

4143
for impl_item in &impl_items {
42-
self.check_trait_impl_item(&env, &assumptions, &trait_items, impl_item)?;
44+
self.check_trait_impl_item(&env, &where_clauses, &trait_items, impl_item)?;
4345
}
4446

4547
Ok(())
@@ -49,7 +51,7 @@ impl super::Check<'_> {
4951
fn check_trait_impl_item(
5052
&self,
5153
env: &Env,
52-
assumptions: &[Hypothesis],
54+
assumptions: &[WhereClause],
5355
trait_items: &[TraitItem],
5456
impl_item: &ImplItem,
5557
) -> Fallible<()> {
@@ -61,15 +63,17 @@ impl super::Check<'_> {
6163
}
6264
}
6365

64-
#[context("check_fn_in_impl")]
65-
#[requires(impl_assumptions.iter().all(|a| a.references_only_placeholder_variables()))]
6666
fn check_fn_in_impl(
6767
&self,
6868
env: &Env,
69-
impl_assumptions: &[Hypothesis],
69+
impl_assumptions: &[WhereClause],
7070
trait_items: &[TraitItem],
7171
ii_fn: &Fn,
7272
) -> Fallible<()> {
73+
assert!(
74+
env.only_universal_variables() && env.encloses((impl_assumptions, trait_items, ii_fn))
75+
);
76+
7377
// Find the corresponding function from the trait:
7478
let ti_fn = match trait_items
7579
.iter()
@@ -90,18 +94,20 @@ impl super::Check<'_> {
9094
input_tys: ii_input_tys,
9195
output_ty: ii_output_ty,
9296
where_clauses: ii_where_clauses,
97+
body: _,
9398
},
9499
FnBoundData {
95100
input_tys: ti_input_tys,
96101
output_ty: ti_output_ty,
97102
where_clauses: ti_where_clauses,
103+
body: _,
98104
},
99105
) = env.instantiate_universally(&self.merge_binders(&ii_fn.binder, &ti_fn.binder)?);
100106

101107
self.prove_goal(
102108
&env,
103109
(impl_assumptions, &ti_where_clauses),
104-
Goal::all(&ii_where_clauses),
110+
&ii_where_clauses,
105111
)?;
106112

107113
if ii_input_tys.len() != ti_input_tys.len() {
@@ -116,14 +122,14 @@ impl super::Check<'_> {
116122
self.prove_goal(
117123
&env,
118124
(impl_assumptions, &ii_where_clauses),
119-
Goal::sub(ti_input_ty, ii_input_ty),
125+
AtomicRelation::sub(ti_input_ty, ii_input_ty),
120126
)?;
121127
}
122128

123129
self.prove_goal(
124130
&env,
125131
(impl_assumptions, &ii_where_clauses),
126-
Goal::sub(ii_output_ty, ti_output_ty),
132+
AtomicRelation::sub(ii_output_ty, ti_output_ty),
127133
)?;
128134

129135
Ok(())
@@ -132,7 +138,7 @@ impl super::Check<'_> {
132138
fn check_associated_ty_value(
133139
&self,
134140
impl_env: &Env,
135-
impl_assumptions: &[Hypothesis],
141+
impl_assumptions: &[WhereClause],
136142
trait_items: &[TraitItem],
137143
impl_value: &AssociatedTyValue,
138144
) -> Fallible<()> {
@@ -169,7 +175,7 @@ impl super::Check<'_> {
169175
self.prove_goal(
170176
&env,
171177
(impl_assumptions, &ti_where_clauses),
172-
Goal::all(&ii_where_clauses),
178+
&ii_where_clauses,
173179
)?;
174180

175181
self.prove_goal(
@@ -178,12 +184,8 @@ impl super::Check<'_> {
178184
ii_ty.well_formed(),
179185
)?;
180186

181-
let ensures = ti_ensures.instantiate_with(&[ii_ty])?;
182-
self.prove_goal(
183-
&env,
184-
(impl_assumptions, &ii_where_clauses),
185-
Goal::all(ensures),
186-
)?;
187+
let ensures: Wcs = ti_ensures.iter().map(|e| e.to_wc(&ii_ty)).collect();
188+
self.prove_goal(&env, (impl_assumptions, &ii_where_clauses), ensures)?;
187189

188190
Ok(())
189191
}

crates/formality-check/src/lib.rs

Lines changed: 23 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,16 @@
11
#![allow(dead_code)]
2-
#![cfg(FIXME)]
32

43
use std::collections::VecDeque;
54

65
use anyhow::bail;
7-
use contracts::requires;
8-
use formality_decl::grammar::{Crate, CrateItem, Program};
9-
use formality_logic::Db;
10-
use formality_logic::Env;
11-
use formality_logic::{prove_universal_goal, UniversalGoalResult};
6+
use formality_prove::{Decls, Env};
7+
use formality_rust::{
8+
grammar::{Crate, CrateItem, Program, WhereClause},
9+
prove::ToWcs,
10+
};
1211
use formality_types::{
1312
cast::Upcast,
14-
grammar::{Fallible, Goal, Hypothesis},
15-
term::Term,
13+
grammar::{Fallible, Wcs},
1614
};
1715

1816
/// Check all crates in the program. The crates must be in dependency order
@@ -44,7 +42,7 @@ mod where_clauses;
4442

4543
struct Check<'p> {
4644
program: &'p Program,
47-
db: Db,
45+
decls: &'p Decls,
4846
}
4947

5048
impl Check<'_> {
@@ -77,28 +75,31 @@ impl Check<'_> {
7775

7876
fn check_crate_item(&self, c: &CrateItem) -> Fallible<()> {
7977
match c {
80-
CrateItem::Adt(v) => self.check_adt(v),
8178
CrateItem::Trait(v) => self.check_trait(v),
8279
CrateItem::TraitImpl(v) => self.check_trait_impl(v),
83-
CrateItem::Fn(v) => self.check_free_fn(v),
80+
CrateItem::Struct(s) => self.check_adt(&s.to_adt()),
81+
CrateItem::Enum(e) => self.check_adt(&e.to_adt()),
82+
CrateItem::Fn(f) => self.check_free_fn(f),
8483
}
8584
}
8685

87-
#[requires(goal.references_only_placeholder_variables())]
8886
fn prove_goal(
8987
&self,
9088
env: &Env,
91-
assumptions: impl Upcast<Vec<Hypothesis>>,
92-
goal: impl Term + Upcast<Goal>,
89+
assumptions: impl Upcast<Vec<WhereClause>>,
90+
goal: impl ToWcs,
9391
) -> Fallible<()> {
94-
let goal: Goal = goal.upcast();
95-
let assumptions = assumptions.upcast();
96-
match prove_universal_goal(&self.db, env, &assumptions, &goal) {
97-
UniversalGoalResult::Yes => Ok(()),
98-
UniversalGoalResult::No => bail!("could not prove `{goal:?}` given `{assumptions:#?}`"),
99-
UniversalGoalResult::Maybe => {
100-
bail!("could not prove `{goal:?}` (ambiguous) given `{assumptions:#?}`")
101-
}
92+
let goal: Wcs = goal.to_wcs();
93+
let assumptions: Vec<WhereClause> = assumptions.upcast();
94+
95+
assert!(env.only_universal_variables());
96+
assert!(env.encloses((&assumptions, &goal)));
97+
98+
let cs = formality_prove::prove(self.decls, env, assumptions.to_wcs(), &goal);
99+
if cs.iter().any(|c| c.unconditionally_true()) {
100+
return Ok(());
102101
}
102+
103+
bail!("failed to prove {goal:?} from {assumptions:?}, got {cs:?}")
103104
}
104105
}

0 commit comments

Comments
 (0)