Finish basic simplifications

This commit is contained in:
Patrick Lühne 2020-05-22 18:14:56 +02:00
parent 3b3f9017ba
commit 0578e99dc2
Signed by: patrick
GPG Key ID: 05F3611E97A70ABF
5 changed files with 103 additions and 49 deletions

View File

@ -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(()) => (),

View File

@ -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),
} }
} }

View File

@ -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);

View File

@ -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, thats it");
break; break;
} }
Ok(())
} }

View File

@ -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());