Finish basic simplifications
This commit is contained in:
parent
3b3f9017ba
commit
0578e99dc2
@ -1,5 +1,5 @@
|
|||||||
pub fn run<P>(program_path: P, specification_path: P, proof_direction:
|
pub fn run<P>(program_path: P, specification_path: P,
|
||||||
crate::problem::ProofDirection)
|
proof_direction: crate::problem::ProofDirection, no_simplify: bool)
|
||||||
where
|
where
|
||||||
P: AsRef<std::path::Path>,
|
P: AsRef<std::path::Path>,
|
||||||
{
|
{
|
||||||
@ -60,6 +60,19 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !no_simplify
|
||||||
|
{
|
||||||
|
match problem.simplify()
|
||||||
|
{
|
||||||
|
Ok(_) => (),
|
||||||
|
Err(error) =>
|
||||||
|
{
|
||||||
|
log::error!("could not simplify translated program: {}", error);
|
||||||
|
std::process::exit(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
match problem.prove(proof_direction)
|
match problem.prove(proof_direction)
|
||||||
{
|
{
|
||||||
Ok(()) => (),
|
Ok(()) => (),
|
||||||
|
@ -19,6 +19,10 @@ enum Command
|
|||||||
/// Proof direction (forward, backward, both)
|
/// Proof direction (forward, backward, both)
|
||||||
#[structopt(long, default_value = "forward")]
|
#[structopt(long, default_value = "forward")]
|
||||||
proof_direction: anthem::problem::ProofDirection,
|
proof_direction: anthem::problem::ProofDirection,
|
||||||
|
|
||||||
|
/// Do not simplify translated program
|
||||||
|
#[structopt(long)]
|
||||||
|
no_simplify: bool,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -35,8 +39,9 @@ fn main()
|
|||||||
program_path,
|
program_path,
|
||||||
specification_path,
|
specification_path,
|
||||||
proof_direction,
|
proof_direction,
|
||||||
|
no_simplify,
|
||||||
}
|
}
|
||||||
=> anthem::commands::verify_program::run(&program_path, &specification_path,
|
=> anthem::commands::verify_program::run(&program_path, &specification_path,
|
||||||
proof_direction),
|
proof_direction, no_simplify),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -44,7 +44,7 @@ impl Problem
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn add_statement(&self, section_kind: SectionKind, mut statement: Statement)
|
pub(crate) fn add_statement(&self, section_kind: SectionKind, statement: Statement)
|
||||||
{
|
{
|
||||||
let mut statements = self.statements.borrow_mut();
|
let mut statements = self.statements.borrow_mut();
|
||||||
let section = statements.entry(section_kind).or_insert(vec![]);
|
let section = statements.entry(section_kind).or_insert(vec![]);
|
||||||
@ -151,6 +151,28 @@ impl Problem
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn simplify(&mut self) -> Result<(), crate::Error>
|
||||||
|
{
|
||||||
|
let mut statements = self.statements.borrow_mut();
|
||||||
|
|
||||||
|
for (_, statements) in statements.iter_mut()
|
||||||
|
{
|
||||||
|
for statement in statements.iter_mut()
|
||||||
|
{
|
||||||
|
match statement.kind
|
||||||
|
{
|
||||||
|
// Only simplify generated formulas
|
||||||
|
| StatementKind::CompletedDefinition(_)
|
||||||
|
| StatementKind::IntegrityConstraint =>
|
||||||
|
crate::simplify(&mut statement.formula)?,
|
||||||
|
_ => (),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
fn print_step_title(&self, step_title: &str, color: &termcolor::ColorSpec)
|
fn print_step_title(&self, step_title: &str, color: &termcolor::ColorSpec)
|
||||||
-> Result<(), crate::Error>
|
-> Result<(), crate::Error>
|
||||||
{
|
{
|
||||||
@ -319,13 +341,8 @@ impl Problem
|
|||||||
self.shell.borrow_mut().print(&format!("{}: ", statement.kind),
|
self.shell.borrow_mut().print(&format!("{}: ", statement.kind),
|
||||||
&termcolor::ColorSpec::new())?;
|
&termcolor::ColorSpec::new())?;
|
||||||
|
|
||||||
match statement.kind
|
// TODO: only perform autonaming when necessary
|
||||||
{
|
crate::autoname_variables(&mut statement.formula);
|
||||||
StatementKind::CompletedDefinition(_)
|
|
||||||
| StatementKind::IntegrityConstraint =>
|
|
||||||
crate::autoname_variables(&mut statement.formula),
|
|
||||||
_ => (),
|
|
||||||
}
|
|
||||||
|
|
||||||
print!("{}", statement.formula);
|
print!("{}", statement.formula);
|
||||||
|
|
||||||
|
@ -18,9 +18,10 @@ impl SimplificationResult
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn remove_unnecessary_exists_parameters(formula: &mut crate::Formula) -> SimplificationResult
|
fn remove_unnecessary_exists_parameters(formula: &mut crate::Formula)
|
||||||
|
-> Result<SimplificationResult, crate::Error>
|
||||||
{
|
{
|
||||||
use crate::Formula;
|
use crate::{Formula, Term};
|
||||||
|
|
||||||
match formula
|
match formula
|
||||||
{
|
{
|
||||||
@ -33,18 +34,18 @@ fn remove_unnecessary_exists_parameters(formula: &mut crate::Formula) -> Simplif
|
|||||||
for argument in arguments
|
for argument in arguments
|
||||||
{
|
{
|
||||||
simplification_result = simplification_result.or(
|
simplification_result = simplification_result.or(
|
||||||
remove_unnecessary_exists_parameters(argument));
|
remove_unnecessary_exists_parameters(argument)?);
|
||||||
}
|
}
|
||||||
|
|
||||||
simplification_result
|
Ok(simplification_result)
|
||||||
},
|
},
|
||||||
Formula::Boolean(_)
|
Formula::Boolean(_)
|
||||||
| Formula::Compare(_)
|
| Formula::Compare(_)
|
||||||
| Formula::Predicate(_) => SimplificationResult::NotSimplified,
|
| Formula::Predicate(_) => Ok(SimplificationResult::NotSimplified),
|
||||||
Formula::Exists(ref mut quantified_formula) =>
|
Formula::Exists(ref mut quantified_formula) =>
|
||||||
{
|
{
|
||||||
let mut simplification_result =
|
let mut simplification_result =
|
||||||
remove_unnecessary_exists_parameters(&mut quantified_formula.argument);
|
remove_unnecessary_exists_parameters(&mut quantified_formula.argument)?;
|
||||||
|
|
||||||
let arguments = match *quantified_formula.argument
|
let arguments = match *quantified_formula.argument
|
||||||
{
|
{
|
||||||
@ -69,31 +70,55 @@ fn remove_unnecessary_exists_parameters(formula: &mut crate::Formula) -> Simplif
|
|||||||
_ => return None,
|
_ => return None,
|
||||||
};
|
};
|
||||||
|
|
||||||
if let foliage::Term::Variable(ref variable) = **left
|
let assigned_term = match (&**left, &**right)
|
||||||
{
|
{
|
||||||
if variable.declaration == *parameter
|
(Term::Variable(ref variable), right)
|
||||||
&& !crate::term_contains_variable(right, parameter)
|
if variable.declaration == *parameter =>
|
||||||
|
right,
|
||||||
|
(left, Term::Variable(ref variable))
|
||||||
|
if variable.declaration == *parameter =>
|
||||||
|
left,
|
||||||
|
_ => return None,
|
||||||
|
};
|
||||||
|
|
||||||
|
let parameter_domain = match parameter.domain()
|
||||||
{
|
{
|
||||||
// TODO: avoid copy
|
Ok(domain) => domain,
|
||||||
return Some((argument_index, crate::copy_term(right)));
|
Err(_) =>
|
||||||
}
|
unreachable!("all variable domains should be assigned at this point"),
|
||||||
|
};
|
||||||
|
|
||||||
|
let is_parameter_integer =
|
||||||
|
parameter_domain == crate::Domain::Integer;
|
||||||
|
|
||||||
|
let is_assigned_term_arithmetic =
|
||||||
|
match crate::is_term_arithmetic(assigned_term)
|
||||||
|
{
|
||||||
|
Ok(is_term_arithmetic) => is_term_arithmetic,
|
||||||
|
Err(error) => return Some(Err(error)),
|
||||||
|
};
|
||||||
|
|
||||||
|
let is_assignment_narrowing = is_parameter_integer
|
||||||
|
&& !is_assigned_term_arithmetic;
|
||||||
|
|
||||||
|
if crate::term_contains_variable(assigned_term, parameter)
|
||||||
|
|| is_assignment_narrowing
|
||||||
|
{
|
||||||
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let foliage::Term::Variable(ref variable) = **right
|
|
||||||
{
|
|
||||||
if variable.declaration == *parameter
|
|
||||||
&& !crate::term_contains_variable(left, parameter)
|
|
||||||
{
|
|
||||||
// TODO: avoid copy
|
// TODO: avoid copy
|
||||||
return Some((argument_index, crate::copy_term(left)));
|
Some(Ok((argument_index, crate::copy_term(assigned_term))))
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
None
|
|
||||||
});
|
});
|
||||||
|
|
||||||
if let Some((assignment_index, assigned_term)) = assignment
|
if let Some(assignment) = assignment
|
||||||
{
|
{
|
||||||
|
let (assignment_index, assigned_term) = match assignment
|
||||||
|
{
|
||||||
|
Err(error) => return Some(Err(error)),
|
||||||
|
Ok(assignment) => assignment,
|
||||||
|
};
|
||||||
|
|
||||||
arguments.remove(assignment_index);
|
arguments.remove(assignment_index);
|
||||||
|
|
||||||
for argument in arguments.iter_mut()
|
for argument in arguments.iter_mut()
|
||||||
@ -107,11 +132,11 @@ fn remove_unnecessary_exists_parameters(formula: &mut crate::Formula) -> Simplif
|
|||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
Some(std::rc::Rc::clone(parameter))
|
Some(Ok(std::rc::Rc::clone(parameter)))
|
||||||
})
|
})
|
||||||
.collect());
|
.collect::<Result<_, _>>()?);
|
||||||
|
|
||||||
simplification_result
|
Ok(simplification_result)
|
||||||
}
|
}
|
||||||
Formula::ForAll(ref mut quantified_formula) =>
|
Formula::ForAll(ref mut quantified_formula) =>
|
||||||
remove_unnecessary_exists_parameters(&mut quantified_formula.argument),
|
remove_unnecessary_exists_parameters(&mut quantified_formula.argument),
|
||||||
@ -225,22 +250,20 @@ fn simplify_trivial_n_ary_formulas(formula: &mut crate::Formula) -> Simplificati
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn simplify(formula: &mut crate::Formula)
|
pub(crate) fn simplify(formula: &mut crate::Formula) -> Result<(), crate::Error>
|
||||||
{
|
{
|
||||||
loop
|
loop
|
||||||
{
|
{
|
||||||
if remove_unnecessary_exists_parameters(formula) == SimplificationResult::Simplified
|
if remove_unnecessary_exists_parameters(formula)? == SimplificationResult::Simplified
|
||||||
|| simplify_quantified_formulas_without_parameters(formula)
|
|| simplify_quantified_formulas_without_parameters(formula)
|
||||||
== SimplificationResult::Simplified
|
== SimplificationResult::Simplified
|
||||||
|| simplify_trivial_n_ary_formulas(formula) == SimplificationResult::Simplified
|
|| simplify_trivial_n_ary_formulas(formula) == SimplificationResult::Simplified
|
||||||
{
|
{
|
||||||
log::debug!("cool, simplified!");
|
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
log::debug!("nope, that’s it");
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -146,11 +146,9 @@ impl<'p> Translator<'p>
|
|||||||
let statement_kind = crate::problem::StatementKind::CompletedDefinition(
|
let statement_kind = crate::problem::StatementKind::CompletedDefinition(
|
||||||
std::rc::Rc::clone(&predicate_declaration));
|
std::rc::Rc::clone(&predicate_declaration));
|
||||||
|
|
||||||
let mut completed_definition = completed_definition(predicate_declaration,
|
let completed_definition = completed_definition(predicate_declaration,
|
||||||
&mut self.definitions);
|
&mut self.definitions);
|
||||||
|
|
||||||
//crate::simplify(&mut completed_definition);
|
|
||||||
|
|
||||||
let statement_name =
|
let statement_name =
|
||||||
format!("completed_definition_{}", predicate_declaration.tptp_statement_name());
|
format!("completed_definition_{}", predicate_declaration.tptp_statement_name());
|
||||||
|
|
||||||
@ -287,8 +285,6 @@ impl<'p> Translator<'p>
|
|||||||
|
|
||||||
let integrity_constraint = crate::universal_closure(open_formula);
|
let integrity_constraint = crate::universal_closure(open_formula);
|
||||||
|
|
||||||
//crate::simplify(&mut integrity_constraint);
|
|
||||||
|
|
||||||
let statement = crate::problem::Statement::new(
|
let statement = crate::problem::Statement::new(
|
||||||
crate::problem::StatementKind::IntegrityConstraint, integrity_constraint)
|
crate::problem::StatementKind::IntegrityConstraint, integrity_constraint)
|
||||||
.with_name("integrity_constraint".to_string());
|
.with_name("integrity_constraint".to_string());
|
||||||
|
Loading…
Reference in New Issue
Block a user