Skip to content

Commit 1c34dcc

Browse files
committed
Don't allow polyequal outside assumes
1 parent 96b187c commit 1c34dcc

File tree

6 files changed

+46
-14
lines changed

6 files changed

+46
-14
lines changed

carcara/src/checker/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,7 @@ impl<'c> ProofChecker<'c> {
334334
previous_command,
335335
discharge: &discharge,
336336
polyeq_time: &mut polyeq_time,
337+
allow_polyeq: !self.config.isabelle_mode,
337338
};
338339

339340
rule(rule_args)?;

carcara/src/checker/parallel/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -395,6 +395,7 @@ impl<'c> ParallelProofChecker<'c> {
395395
previous_command,
396396
discharge: &discharge,
397397
polyeq_time: &mut polyeq_time,
398+
allow_polyeq: !self.config.isabelle_mode,
398399
};
399400

400401
rule(rule_args)?;

carcara/src/checker/rules/mod.rs

+2
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ pub struct RuleArgs<'a> {
2626
pub(super) discharge: &'a [&'a ProofCommand],
2727

2828
pub(super) polyeq_time: &'a mut Duration,
29+
30+
pub(super) allow_polyeq: bool,
2931
}
3032

3133
#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)]

carcara/src/checker/rules/reflexivity.rs

+12-4
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,26 @@ pub fn refl(
1313
pool,
1414
context,
1515
polyeq_time,
16+
allow_polyeq,
1617
..
1718
}: RuleArgs,
1819
) -> RuleResult {
20+
let mut compare = |a, b| -> bool {
21+
if allow_polyeq {
22+
alpha_equiv(a, b, polyeq_time)
23+
} else {
24+
a == b
25+
}
26+
};
27+
1928
assert_clause_len(conclusion, 1)?;
2029

2130
let (left, right) = match_term_err!((= l r) = &conclusion[0])?;
2231

2332
// If the two terms are directly identical, we don't need to do any more work. We make sure to
2433
// do this check before we try to get the context substitution, because `refl` can be used
2534
// outside of any subproof
26-
if alpha_equiv(left, right, polyeq_time) {
35+
if compare(left, right) {
2736
return Ok(());
2837
}
2938

@@ -36,10 +45,9 @@ pub fn refl(
3645
// don't compute the new left and right terms until they are needed, to avoid doing unnecessary
3746
// work
3847
let new_left = context.apply(pool, left);
39-
let result = alpha_equiv(&new_left, right, polyeq_time) || {
48+
let result = compare(&new_left, right) || {
4049
let new_right = context.apply(pool, right);
41-
alpha_equiv(left, &new_right, polyeq_time)
42-
|| alpha_equiv(&new_left, &new_right, polyeq_time)
50+
compare(left, &new_right) || compare(&new_left, &new_right)
4351
};
4452
rassert!(
4553
result,

carcara/src/checker/rules/subproof.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ pub fn subproof(
1313
previous_command,
1414
discharge,
1515
polyeq_time,
16+
allow_polyeq,
1617
..
1718
}: RuleArgs,
1819
) -> RuleResult {
@@ -44,7 +45,11 @@ pub fn subproof(
4445
}
4546
};
4647

47-
assert_polyeq(conclusion.last().unwrap(), &phi, polyeq_time)
48+
if allow_polyeq {
49+
assert_polyeq(conclusion.last().unwrap(), &phi, polyeq_time)
50+
} else {
51+
assert_eq(conclusion.last().unwrap(), &phi)
52+
}
4853
}
4954

5055
pub fn bind(

carcara/src/checker/rules/tautology.rs

+24-9
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use super::{
2-
assert_clause_len, assert_eq, assert_num_premises, assert_polyeq, get_premise_term,
3-
CheckerError, RuleArgs, RuleResult,
2+
assert_clause_len, assert_eq, assert_num_premises, get_premise_term, CheckerError, RuleArgs,
3+
RuleResult,
44
};
55
use crate::{ast::*, checker::rules::assert_operation_len};
66

@@ -258,7 +258,22 @@ pub fn not_ite2(RuleArgs { conclusion, premises, .. }: RuleArgs) -> RuleResult {
258258
assert_eq(phi_2, conclusion[1].remove_negation_err()?)
259259
}
260260

261-
pub fn ite_intro(RuleArgs { conclusion, polyeq_time, .. }: RuleArgs) -> RuleResult {
261+
pub fn ite_intro(
262+
RuleArgs {
263+
conclusion,
264+
polyeq_time,
265+
allow_polyeq,
266+
..
267+
}: RuleArgs,
268+
) -> RuleResult {
269+
let mut compare = |a, b| -> bool {
270+
if allow_polyeq {
271+
polyeq(a, b, polyeq_time)
272+
} else {
273+
a == b
274+
}
275+
};
276+
262277
assert_clause_len(conclusion, 1)?;
263278

264279
let (root_term, right_side) = match_term_err!((= t u) = &conclusion[0])?;
@@ -278,25 +293,25 @@ pub fn ite_intro(RuleArgs { conclusion, polyeq_time, .. }: RuleArgs) -> RuleResu
278293
// ```
279294
// For cases like this, we first check if `t` equals the right side term modulo reordering of
280295
// equalities. If not, we unwrap the conjunction and continue checking the rule normally.
281-
if polyeq(root_term, right_side, polyeq_time) {
296+
if compare(root_term, right_side) {
282297
return Ok(());
283298
}
284299
let us = match_term_err!((and ...) = right_side)?;
285300

286301
// `us` must be a conjunction where the first term is the root term
287-
assert_polyeq(&us[0], root_term, polyeq_time)?;
302+
if !allow_polyeq || !compare(&us[0], root_term) {
303+
assert_eq(&us[0], root_term)?;
304+
}
288305

289306
// The remaining terms in `us` should be of the correct form
290307
for u_i in &us[1..] {
291308
let (cond, (a, b), (c, d)) = match_term_err!((ite cond (= a b) (= c d)) = u_i)?;
292309

293310
let mut is_valid = |r_1, s_1, r_2, s_2| {
294311
// s_1 == s_2 == (ite cond r_1 r_2)
295-
if polyeq(s_1, s_2, polyeq_time) {
312+
if compare(s_1, s_2) {
296313
if let Some((a, b, c)) = match_term!((ite a b c) = s_1) {
297-
return polyeq(a, cond, polyeq_time)
298-
&& polyeq(b, r_1, polyeq_time)
299-
&& polyeq(c, r_2, polyeq_time);
314+
return compare(a, cond) && compare(b, r_1) && compare(c, r_2);
300315
}
301316
}
302317
false

0 commit comments

Comments
 (0)