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:
crate::problem::ProofDirection)
pub fn run<P>(program_path: P, specification_path: P,
proof_direction: crate::problem::ProofDirection, no_simplify: bool)
where
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)
{
Ok(()) => (),

View File

@ -19,6 +19,10 @@ enum Command
/// Proof direction (forward, backward, both)
#[structopt(long, default_value = "forward")]
proof_direction: anthem::problem::ProofDirection,
/// Do not simplify translated program
#[structopt(long)]
no_simplify: bool,
}
}
@ -35,8 +39,9 @@ fn main()
program_path,
specification_path,
proof_direction,
no_simplify,
}
=> 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 section = statements.entry(section_kind).or_insert(vec![]);
@ -151,6 +151,28 @@ impl Problem
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)
-> Result<(), crate::Error>
{
@ -319,13 +341,8 @@ impl Problem
self.shell.borrow_mut().print(&format!("{}: ", statement.kind),
&termcolor::ColorSpec::new())?;
match statement.kind
{
StatementKind::CompletedDefinition(_)
| StatementKind::IntegrityConstraint =>
crate::autoname_variables(&mut statement.formula),
_ => (),
}
// TODO: only perform autonaming when necessary
crate::autoname_variables(&mut 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
{
@ -33,18 +34,18 @@ fn remove_unnecessary_exists_parameters(formula: &mut crate::Formula) -> Simplif
for argument in arguments
{
simplification_result = simplification_result.or(
remove_unnecessary_exists_parameters(argument));
remove_unnecessary_exists_parameters(argument)?);
}
simplification_result
Ok(simplification_result)
},
Formula::Boolean(_)
| Formula::Compare(_)
| Formula::Predicate(_) => SimplificationResult::NotSimplified,
| Formula::Predicate(_) => Ok(SimplificationResult::NotSimplified),
Formula::Exists(ref mut quantified_formula) =>
{
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
{
@ -69,31 +70,55 @@ fn remove_unnecessary_exists_parameters(formula: &mut crate::Formula) -> Simplif
_ => return None,
};
if let foliage::Term::Variable(ref variable) = **left
let assigned_term = match (&**left, &**right)
{
if variable.declaration == *parameter
&& !crate::term_contains_variable(right, parameter)
(Term::Variable(ref variable), right)
if variable.declaration == *parameter =>
right,
(left, Term::Variable(ref variable))
if variable.declaration == *parameter =>
left,
_ => return None,
};
let parameter_domain = match parameter.domain()
{
Ok(domain) => domain,
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)
{
// TODO: avoid copy
return Some((argument_index, crate::copy_term(right)));
}
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
return Some((argument_index, crate::copy_term(left)));
}
}
None
// TODO: avoid copy
Some(Ok((argument_index, crate::copy_term(assigned_term))))
});
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);
for argument in arguments.iter_mut()
@ -107,11 +132,11 @@ fn remove_unnecessary_exists_parameters(formula: &mut crate::Formula) -> Simplif
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) =>
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
{
if remove_unnecessary_exists_parameters(formula) == SimplificationResult::Simplified
if remove_unnecessary_exists_parameters(formula)? == SimplificationResult::Simplified
|| simplify_quantified_formulas_without_parameters(formula)
== SimplificationResult::Simplified
|| simplify_trivial_n_ary_formulas(formula) == SimplificationResult::Simplified
{
log::debug!("cool, simplified!");
continue;
}
log::debug!("nope, thats it");
break;
}
Ok(())
}

View File

@ -146,11 +146,9 @@ impl<'p> Translator<'p>
let statement_kind = crate::problem::StatementKind::CompletedDefinition(
std::rc::Rc::clone(&predicate_declaration));
let mut completed_definition = completed_definition(predicate_declaration,
let completed_definition = completed_definition(predicate_declaration,
&mut self.definitions);
//crate::simplify(&mut completed_definition);
let 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);
//crate::simplify(&mut integrity_constraint);
let statement = crate::problem::Statement::new(
crate::problem::StatementKind::IntegrityConstraint, integrity_constraint)
.with_name("integrity_constraint".to_string());