Skip to content

Commit b5742f8

Browse files
authored
Update for arguments being only terms (#47)
* Update for arguments being only terms The main impact is that ProofArg is removed and everything is made more uniform since arguments are only terms. * format * Remove test for parsing assignment arg since it is no longer relevant * Simplifying building substitution when checking `forall_inst` * remove unused error
1 parent a2126bf commit b5742f8

17 files changed

+44
-172
lines changed

carcara/src/ast/node.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,7 @@ pub struct StepNode {
218218
pub premises: Vec<Rc<ProofNode>>,
219219

220220
/// The step arguments, given via the `:args` attribute.
221-
pub args: Vec<ProofArg>,
221+
pub args: Vec<Rc<Term>>,
222222

223223
/// The local premises that this step discharges, given via the `:discharge` attribute.
224224
pub discharge: Vec<Rc<ProofNode>>,

carcara/src/ast/polyeq.rs

+1-12
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,7 @@
1010
use rug::Rational;
1111

1212
use super::{
13-
AnchorArg, BindingList, Constant, Operator, ProofArg, ProofCommand, ProofStep, Rc, Sort,
14-
Subproof, Term,
13+
AnchorArg, BindingList, Constant, Operator, ProofCommand, ProofStep, Rc, Sort, Subproof, Term,
1514
};
1615
use crate::utils::HashMapStack;
1716
use std::time::{Duration, Instant};
@@ -683,16 +682,6 @@ impl PolyeqComparable for AnchorArg {
683682
}
684683
}
685684

686-
impl PolyeqComparable for ProofArg {
687-
fn eq(comp: &mut Polyeq, a: &Self, b: &Self) -> bool {
688-
match (a, b) {
689-
(ProofArg::Term(a), ProofArg::Term(b)) => comp.eq(a, b),
690-
(ProofArg::Assign(sa, ta), ProofArg::Assign(sb, tb)) => sa == sb && comp.eq(ta, tb),
691-
_ => false,
692-
}
693-
}
694-
}
695-
696685
impl PolyeqComparable for ProofCommand {
697686
fn eq(comp: &mut Polyeq, a: &Self, b: &Self) -> bool {
698687
match (a, b) {

carcara/src/ast/printer.rs

+2-13
Original file line numberDiff line numberDiff line change
@@ -356,10 +356,10 @@ impl<'a> AlethePrinter<'a> {
356356

357357
if let [head, tail @ ..] = step.args.as_slice() {
358358
write!(self.inner, " :args (")?;
359-
self.write_proof_arg(head)?;
359+
head.print_with_sharing(self)?;
360360
for arg in tail {
361361
write!(self.inner, " ")?;
362-
self.write_proof_arg(arg)?;
362+
arg.print_with_sharing(self)?;
363363
}
364364
write!(self.inner, ")")?;
365365
}
@@ -378,17 +378,6 @@ impl<'a> AlethePrinter<'a> {
378378
Ok(())
379379
}
380380

381-
fn write_proof_arg(&mut self, arg: &ProofArg) -> io::Result<()> {
382-
match arg {
383-
ProofArg::Term(t) => t.print_with_sharing(self),
384-
ProofArg::Assign(name, value) => {
385-
write!(self.inner, "(:= {} ", name)?;
386-
value.print_with_sharing(self)?;
387-
write!(self.inner, ")")
388-
}
389-
}
390-
}
391-
392381
fn write_lia_smt_instance(&mut self, clause: &[Rc<Term>]) -> io::Result<()> {
393382
for term in clause.iter().dedup() {
394383
write!(self.inner, "(assert (not ")?;

carcara/src/ast/proof.rs

+1-32
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
use super::{ProofIter, Rc, SortedVar, Term};
2-
use crate::CheckerError;
32

43
/// A proof in the Alethe format.
54
#[derive(Debug, Clone)]
@@ -46,23 +45,13 @@ pub struct ProofStep {
4645
pub premises: Vec<(usize, usize)>,
4746

4847
/// The step arguments, given via the `:args` attribute.
49-
pub args: Vec<ProofArg>,
48+
pub args: Vec<Rc<Term>>,
5049

5150
/// The local premises that this step discharges, given via the `:discharge` attribute, and
5251
/// indexed similarly to premises.
5352
pub discharge: Vec<(usize, usize)>,
5453
}
5554

56-
/// An argument for a `step` command.
57-
#[derive(Debug, Clone, PartialEq, Eq)]
58-
pub enum ProofArg {
59-
/// An argument that is just a term.
60-
Term(Rc<Term>),
61-
62-
/// An argument of the form `(:= <symbol> <term>)`.
63-
Assign(String, Rc<Term>),
64-
}
65-
6655
/// A subproof.
6756
///
6857
/// Subproofs are started by `anchor` commands, and contain a series of steps, possibly including
@@ -141,26 +130,6 @@ impl ProofCommand {
141130
}
142131
}
143132

144-
impl ProofArg {
145-
/// If this argument is a "term style" argument, extracts that term from it. Otherwise, returns
146-
/// an error.
147-
pub fn as_term(&self) -> Result<&Rc<Term>, CheckerError> {
148-
match self {
149-
ProofArg::Term(t) => Ok(t),
150-
ProofArg::Assign(s, t) => Err(CheckerError::ExpectedTermStyleArg(s.clone(), t.clone())),
151-
}
152-
}
153-
154-
/// If this argument is an "assign style" argument, extracts the variable name and the value
155-
/// term from it. Otherwise, returns an error.
156-
pub fn as_assign(&self) -> Result<(&String, &Rc<Term>), CheckerError> {
157-
match self {
158-
ProofArg::Assign(s, t) => Ok((s, t)),
159-
ProofArg::Term(t) => Err(CheckerError::ExpectedAssignStyleArg(t.clone())),
160-
}
161-
}
162-
}
163-
164133
impl AnchorArg {
165134
/// Returns `Some` if the anchor arg is a "variable" style argument.
166135
pub fn as_variable(&self) -> Option<&SortedVar> {

carcara/src/checker/error.rs

-6
Original file line numberDiff line numberDiff line change
@@ -126,12 +126,6 @@ pub enum CheckerError {
126126
#[error("expected 'let' term, got '{0}'")]
127127
ExpectedLetTerm(Rc<Term>),
128128

129-
#[error("expected term style argument, got assign style argument: '(:= {0} {1})'")]
130-
ExpectedTermStyleArg(String, Rc<Term>),
131-
132-
#[error("expected assign style '(:= ...)' argument, got term style argument: '{0}'")]
133-
ExpectedAssignStyleArg(Rc<Term>),
134-
135129
#[error("expected term {0} to be a prefix of {1}")]
136130
ExpectedToBePrefix(Rc<Term>, Rc<Term>),
137131

carcara/src/checker/rules/linear_arithmetic.rs

-1
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,6 @@ pub fn la_generic(RuleArgs { conclusion, args, .. }: RuleArgs) -> RuleResult {
263263
let args: Vec<_> = args
264264
.iter()
265265
.map(|a| {
266-
let a = a.as_term()?;
267266
a.as_fraction()
268267
.ok_or_else(|| CheckerError::ExpectedAnyNumber(a.clone()))
269268
})

carcara/src/checker/rules/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ pub type Rule = fn(RuleArgs) -> RuleResult;
1515
pub struct RuleArgs<'a> {
1616
pub(super) conclusion: &'a [Rc<Term>],
1717
pub(super) premises: &'a [Premise<'a>],
18-
pub(super) args: &'a [ProofArg],
18+
pub(super) args: &'a [Rc<Term>],
1919
pub(super) pool: &'a mut dyn TermPool,
2020
pub(super) context: &'a mut ContextStack,
2121

@@ -85,7 +85,7 @@ fn assert_clause_len<T: Into<Range>>(clause: &[Rc<Term>], range: T) -> RuleResul
8585
Ok(())
8686
}
8787

88-
fn assert_num_args<T: Into<Range>>(args: &[ProofArg], range: T) -> RuleResult {
88+
fn assert_num_args<T: Into<Range>>(args: &[Rc<Term>], range: T) -> RuleResult {
8989
let range = range.into();
9090
if !range.contains(args.len()) {
9191
return Err(CheckerError::WrongNumberOfArgs(range, args.len()));

carcara/src/checker/rules/quantifier.rs

+18-31
Original file line numberDiff line numberDiff line change
@@ -17,31 +17,18 @@ pub fn forall_inst(
1717

1818
assert_num_args(args, bindings.len())?;
1919

20-
// Since the bindings and arguments may not be in the same order, we collect the bindings into
21-
// a hash set, and remove each binding from it as we find the associated argument
22-
let mut bindings: IndexSet<_> = bindings.iter().cloned().collect();
23-
let substitution: IndexMap<_, _> = args
20+
// iterate over the bindings and arguments simultaneously, building the substitution
21+
let substitution: IndexMap<_, _> = bindings
2422
.iter()
25-
.map(|arg| {
26-
let (arg_name, arg_value) = arg.as_assign()?;
27-
let arg_sort = pool.sort(arg_value);
28-
rassert!(
29-
bindings.remove(&(arg_name.clone(), arg_sort.clone())),
30-
QuantifierError::NoBindingMatchesArg(arg_name.clone())
31-
);
32-
33-
let ident_term = (arg_name.clone(), arg_sort).into();
34-
Ok((pool.add(ident_term), arg_value.clone()))
23+
.zip(args)
24+
.map(|((var_name, sort), value)| {
25+
assert_eq(sort, &pool.sort(value))?;
26+
let var = pool.add(Term::new_var(var_name, sort.clone()));
27+
Ok((var.clone(), value.clone()))
3528
})
3629
.collect::<Result<_, CheckerError>>()?;
3730
let mut substitution = Substitution::new(pool, substitution)?;
3831

39-
// All bindings were accounted for in the arguments
40-
rassert!(
41-
bindings.is_empty(),
42-
QuantifierError::NoArgGivenForBinding(bindings.iter().next().unwrap().0.clone())
43-
);
44-
4532
// Equalities may be reordered, and the application of the substitution might rename bound
4633
// variables, so we need to compare for alpha-equivalence here
4734
let expected = substitution.apply(pool, original);
@@ -325,47 +312,47 @@ mod tests {
325312
",
326313
"Simple working examples" {
327314
"(step t1 (cl (or (not (forall ((p Bool)) p)) q))
328-
:rule forall_inst :args ((:= p q)))": true,
315+
:rule forall_inst :args (q))": true,
329316

330317
"(step t1 (cl (or (not (forall ((x Real) (y Real)) (= x y))) (= a b)))
331-
:rule forall_inst :args ((:= x a) (:= y b)))": true,
318+
:rule forall_inst :args (a b))": true,
332319

333320
"(step t1 (cl (or (not (forall ((x Real)) (= x a))) (= a a)))
334-
:rule forall_inst :args ((:= x a)))": true,
321+
:rule forall_inst :args (a))": true,
335322

336323
"(step t1 (cl (or (not (forall ((p Bool)) p)) (ite q (= a b) (and (= a 0.0) true))))
337-
:rule forall_inst :args ((:= p (ite q (= a b) (and (= a 0.0) true)))))": true,
324+
:rule forall_inst :args ((ite q (= a b) (and (= a 0.0) true))))": true,
338325
}
339326
"Equalities may be flipped" {
340327
"(step t1 (cl (or (not (forall ((x Real) (y Real)) (and (= x y) (= 1 0))))
341-
(and (= b a) (= 1 0)))) :rule forall_inst :args ((:= x a) (:= y b)))": true,
328+
(and (= b a) (= 1 0)))) :rule forall_inst :args (a b))": true,
342329
}
343330
"Bound variables may be renamed by substitution" {
344331
// The variable shadowing makes it so the substitution applied by Carcara renames p
345332
"(step t1 (cl (or
346333
(not (forall ((p Bool) (r Bool)) (and p (forall ((p Bool)) p))))
347334
(and q (forall ((p Bool)) p))
348-
)) :rule forall_inst :args ((:= p q) (:= r q)))": true,
335+
)) :rule forall_inst :args (q q))": true,
349336
}
350337
"Argument is not in quantifier bindings" {
351338
"(step t1 (cl (or (not (forall ((x Real)) (= x a))) (= b 0.0)))
352-
:rule forall_inst :args ((:= x b) (:= a 0.0)))": false,
339+
:rule forall_inst :args (b 0.0))": false,
353340
}
354341
"Binding has no associated substitution" {
355342
"(step t1 (cl (or (not (forall ((x Real) (y Real)) (= x x))) (= a a)))
356-
:rule forall_inst :args ((:= x a)))": false,
343+
:rule forall_inst :args (a))": false,
357344
}
358345
"Substitution was not applied" {
359346
"(step t1 (cl (or (not (forall ((x Real) (y Real)) (= x y))) (= x b)))
360-
:rule forall_inst :args ((:= x a) (:= y b)))": false,
347+
:rule forall_inst :args (a b))": false,
361348
}
362349
"Applied substitution was not passed as argument" {
363350
"(step t1 (cl (or (not (forall ((x Real) (y Real)) (= x y))) (= a b)))
364-
:rule forall_inst :args ((:= x a)))": false,
351+
:rule forall_inst :args (a))": false,
365352
}
366353
"Wrong type of rule argument" {
367354
"(step t1 (cl (or (not (forall ((x Real) (y Real)) (= x y))) (= a b)))
368-
:rule forall_inst :args ((:= x a) b))": false,
355+
:rule forall_inst :args ((= x a) b))": false,
369356
}
370357
}
371358
}

carcara/src/checker/rules/resolution.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ pub fn strict_resolution(
132132

133133
fn apply_generic_resolution<'a, C: ClauseCollection<'a>>(
134134
premises: &'a [Premise],
135-
args: &'a [ProofArg],
135+
args: &'a [Rc<Term>],
136136
pool: &mut dyn TermPool,
137137
) -> Result<C, CheckerError> {
138138
assert_num_premises(premises, 2..)?;
@@ -142,8 +142,8 @@ fn apply_generic_resolution<'a, C: ClauseCollection<'a>>(
142142
let args: Vec<_> = args
143143
.chunks(2)
144144
.map(|chunk| {
145-
let pivot = chunk[0].as_term()?.remove_all_negations();
146-
let polarity = chunk[1].as_term()?;
145+
let pivot = chunk[0].remove_all_negations();
146+
let polarity = chunk[1].clone();
147147
let polarity = if polarity.is_bool_true() {
148148
true
149149
} else if polarity.is_bool_false() {

carcara/src/checker/rules/strings.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -340,7 +340,7 @@ pub fn concat_eq(
340340
match_term_err!((= x y) = &conclusion[0])?;
341341

342342
let term = get_premise_term(&premises[0])?;
343-
let rev = args[0].as_term()?.as_bool_err()?;
343+
let rev = args[0].as_bool_err()?;
344344
let (s, t) = match_term_err!((= s t) = term)?;
345345

346346
let (ss, ts) = strip_prefix_or_suffix(pool, s.clone(), t.clone(), rev, polyeq_time)?;
@@ -374,7 +374,7 @@ pub fn concat_unify(
374374

375375
let term = get_premise_term(&premises[0])?;
376376
let prefixes = get_premise_term(&premises[1])?;
377-
let rev = args[0].as_term()?.as_bool_err()?;
377+
let rev = args[0].as_bool_err()?;
378378
let (s, t) = match_term_err!((= s t) = term)?;
379379
let (s_1, t_1) = match_term_err!((= (strlen s_1) (strlen t_1)) = prefixes)?;
380380

@@ -407,7 +407,7 @@ pub fn concat_conflict(
407407
assert_clause_len(conclusion, 1)?;
408408

409409
let term = get_premise_term(&premises[0])?;
410-
let rev = args[0].as_term()?.as_bool_err()?;
410+
let rev = args[0].as_bool_err()?;
411411
if conclusion[0].as_bool_err()? {
412412
return Err(CheckerError::ExpectedBoolConstant(
413413
false,
@@ -890,7 +890,7 @@ pub fn string_decompose(
890890
assert_clause_len(conclusion, 1)?;
891891

892892
let term = get_premise_term(&premises[0])?;
893-
let rev = args[0].as_term()?.as_bool_err()?;
893+
let rev = args[0].as_bool_err()?;
894894
let (t, n) = match_term_err!((>= (strlen t) n) = term)?;
895895

896896
match_term_err!(
@@ -919,7 +919,7 @@ pub fn string_length_pos(RuleArgs { args, conclusion, polyeq_time, .. }: RuleArg
919919
assert_num_args(args, 1)?;
920920
assert_clause_len(conclusion, 1)?;
921921

922-
let t = args[0].as_term()?;
922+
let t = &args[0];
923923
let (((t_1, _), (t_2, _)), (t_3, _)) = match_term_err!(
924924
(or
925925
(and

carcara/src/elaborator/mod.rs

+1-4
Original file line numberDiff line numberDiff line change
@@ -223,10 +223,7 @@ impl<'e> Elaborator<'e> {
223223
clause: vec![term.clone()],
224224
rule: "resolution".to_owned(),
225225
premises: vec![new_assume, equiv1_step],
226-
args: vec![
227-
ProofArg::Term(premise),
228-
ProofArg::Term(self.pool.bool_true()),
229-
],
226+
args: vec![premise, self.pool.bool_true()],
230227
..Default::default()
231228
}))
232229
}

carcara/src/elaborator/reordering.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,8 @@ fn recompute_resolution(step: &StepNode) -> Vec<Rc<Term>> {
6363
.args
6464
.chunks(2)
6565
.map(|chunk| {
66-
let pivot = chunk[0].as_term().unwrap();
67-
let polarity = chunk[1].as_term().unwrap().is_bool_true();
66+
let pivot = &chunk[0];
67+
let polarity = chunk[1].is_bool_true();
6868
(pivot, polarity)
6969
})
7070
.collect();

carcara/src/elaborator/resolution.rs

+1-5
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,7 @@ pub fn resolution(
2727
clause: Vec::new(),
2828
rule: "resolution".to_owned(),
2929
premises: vec![step.premises[0].clone(), true_step],
30-
args: [true, false]
31-
.map(|a| ProofArg::Term(pool.bool_constant(a)))
32-
.to_vec(),
30+
args: [true, false].map(|a| pool.bool_constant(a)).to_vec(),
3331
..Default::default()
3432
})));
3533
}
@@ -62,7 +60,6 @@ pub fn resolution(
6260
let pivots = pivot_trace
6361
.into_iter()
6462
.flat_map(|(pivot, polarity)| [pivot, pool.bool_constant(polarity)])
65-
.map(ProofArg::Term)
6663
.collect();
6764

6865
let mut resolution_step = StepNode {
@@ -128,7 +125,6 @@ pub fn resolution(
128125
// original resolution step's conclusion
129126
let args = [c, pool.bool_true(), quadruple_not_c, pool.bool_true()]
130127
.into_iter()
131-
.map(ProofArg::Term)
132128
.collect();
133129

134130
Ok(Rc::new(ProofNode::Step(StepNode {

carcara/src/elaborator/transitivity.rs

-1
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,6 @@ fn flip_eq_transitive_premises(
267267
let args: Vec<_> = resolution_pivots
268268
.into_iter()
269269
.flat_map(|(_, pivot, _)| [pivot, pool.bool_false()])
270-
.map(ProofArg::Term)
271270
.collect();
272271

273272
Rc::new(ProofNode::Step(StepNode {

0 commit comments

Comments
 (0)