With this patch, properties specific to variable, function, and predicate declarations are directly stored within those objects rather than external maps that need to be queried via traits. This greatly simplifies many parts of the logic. This is made possible by implementing a custom foliage flavor, which makes it possible to swap the built-in declaration types for extended versions of those types that fulfill certain requirements.
245 lines
8.1 KiB
Rust
245 lines
8.1 KiB
Rust
fn replace_variables_in_term(term: &mut crate::Term,
|
|
old_variable_declarations: &crate::VariableDeclarations,
|
|
new_variable_declarations: &crate::VariableDeclarations)
|
|
{
|
|
assert_eq!(old_variable_declarations.len(), new_variable_declarations.len());
|
|
|
|
use crate::Term;
|
|
|
|
match term
|
|
{
|
|
Term::BinaryOperation(binary_operation) =>
|
|
{
|
|
replace_variables_in_term(&mut binary_operation.left, old_variable_declarations,
|
|
new_variable_declarations);
|
|
replace_variables_in_term(&mut binary_operation.right, old_variable_declarations,
|
|
new_variable_declarations);
|
|
},
|
|
Term::Function(function) =>
|
|
for mut argument in &mut function.arguments
|
|
{
|
|
replace_variables_in_term(&mut argument, old_variable_declarations,
|
|
new_variable_declarations);
|
|
},
|
|
Term::UnaryOperation(unary_operation) =>
|
|
replace_variables_in_term(&mut unary_operation.argument, old_variable_declarations,
|
|
new_variable_declarations),
|
|
Term::Variable(variable) =>
|
|
if let Some(index) = old_variable_declarations.iter().enumerate()
|
|
.find_map(
|
|
|(index, variable_declaration)|
|
|
{
|
|
match *variable_declaration == variable.declaration
|
|
{
|
|
true => Some(index),
|
|
false => None,
|
|
}
|
|
})
|
|
{
|
|
variable.declaration = std::rc::Rc::clone(&new_variable_declarations[index]);
|
|
},
|
|
Term::Boolean(_)
|
|
| Term::Integer(_)
|
|
| Term::SpecialInteger(_)
|
|
| Term::String(_) => (),
|
|
}
|
|
}
|
|
|
|
fn replace_variables_in_formula(formula: &mut crate::Formula,
|
|
old_variable_declarations: &crate::VariableDeclarations,
|
|
new_variable_declarations: &crate::VariableDeclarations)
|
|
{
|
|
use crate::Formula;
|
|
|
|
match formula
|
|
{
|
|
Formula::And(arguments)
|
|
| Formula::IfAndOnlyIf(arguments)
|
|
| Formula::Or(arguments) =>
|
|
for argument in arguments
|
|
{
|
|
replace_variables_in_formula(argument, old_variable_declarations,
|
|
new_variable_declarations);
|
|
},
|
|
Formula::Compare(compare) =>
|
|
{
|
|
replace_variables_in_term(&mut compare.left, old_variable_declarations,
|
|
new_variable_declarations);
|
|
replace_variables_in_term(&mut compare.right, old_variable_declarations,
|
|
new_variable_declarations);
|
|
},
|
|
Formula::Exists(quantified_formula)
|
|
| Formula::ForAll(quantified_formula) =>
|
|
replace_variables_in_formula(&mut quantified_formula.argument,
|
|
old_variable_declarations, new_variable_declarations),
|
|
Formula::Implies(implies) =>
|
|
{
|
|
replace_variables_in_formula(&mut implies.antecedent, old_variable_declarations,
|
|
new_variable_declarations);
|
|
replace_variables_in_formula(&mut implies.implication, old_variable_declarations,
|
|
new_variable_declarations);
|
|
},
|
|
Formula::Not(argument) =>
|
|
replace_variables_in_formula(argument, old_variable_declarations,
|
|
new_variable_declarations),
|
|
Formula::Predicate(predicate) =>
|
|
for mut argument in &mut predicate.arguments
|
|
{
|
|
replace_variables_in_term(&mut argument, old_variable_declarations,
|
|
new_variable_declarations);
|
|
},
|
|
Formula::Boolean(_) => (),
|
|
}
|
|
}
|
|
|
|
fn replace_variable_in_term_with_term(term: &mut crate::Term,
|
|
variable_declaration: &crate::VariableDeclaration, replacement_term: &crate::Term)
|
|
{
|
|
use crate::Term;
|
|
|
|
match term
|
|
{
|
|
Term::BinaryOperation(binary_operation) =>
|
|
{
|
|
replace_variable_in_term_with_term(&mut binary_operation.left, variable_declaration,
|
|
replacement_term);
|
|
replace_variable_in_term_with_term(&mut binary_operation.right, variable_declaration,
|
|
replacement_term);
|
|
},
|
|
Term::Function(function) =>
|
|
for mut argument in &mut function.arguments
|
|
{
|
|
replace_variable_in_term_with_term(&mut argument, variable_declaration,
|
|
replacement_term);
|
|
},
|
|
Term::UnaryOperation(unary_operation) =>
|
|
replace_variable_in_term_with_term(&mut unary_operation.argument, variable_declaration,
|
|
replacement_term),
|
|
Term::Variable(variable) =>
|
|
if *variable.declaration == *variable_declaration
|
|
{
|
|
*term = copy_term(replacement_term);
|
|
},
|
|
Term::Boolean(_)
|
|
| Term::Integer(_)
|
|
| Term::SpecialInteger(_)
|
|
| Term::String(_) => (),
|
|
}
|
|
}
|
|
|
|
pub(crate) fn replace_variable_in_formula_with_term(formula: &mut crate::Formula,
|
|
variable_declaration: &crate::VariableDeclaration, replacement_term: &crate::Term)
|
|
{
|
|
use crate::Formula;
|
|
|
|
match formula
|
|
{
|
|
Formula::And(arguments)
|
|
| Formula::IfAndOnlyIf(arguments)
|
|
| Formula::Or(arguments) =>
|
|
for argument in arguments
|
|
{
|
|
replace_variable_in_formula_with_term(argument, variable_declaration,
|
|
replacement_term);
|
|
},
|
|
Formula::Compare(compare) =>
|
|
{
|
|
replace_variable_in_term_with_term(&mut compare.left, variable_declaration,
|
|
replacement_term);
|
|
replace_variable_in_term_with_term(&mut compare.right, variable_declaration,
|
|
replacement_term);
|
|
},
|
|
Formula::Exists(quantified_formula)
|
|
| Formula::ForAll(quantified_formula) =>
|
|
replace_variable_in_formula_with_term(&mut quantified_formula.argument,
|
|
variable_declaration, replacement_term),
|
|
Formula::Implies(implies) =>
|
|
{
|
|
replace_variable_in_formula_with_term(&mut implies.antecedent, variable_declaration,
|
|
replacement_term);
|
|
replace_variable_in_formula_with_term(&mut implies.implication, variable_declaration,
|
|
replacement_term);
|
|
},
|
|
Formula::Not(argument) =>
|
|
replace_variable_in_formula_with_term(argument, variable_declaration, replacement_term),
|
|
Formula::Predicate(predicate) =>
|
|
for mut argument in &mut predicate.arguments
|
|
{
|
|
replace_variable_in_term_with_term(&mut argument, variable_declaration,
|
|
replacement_term);
|
|
},
|
|
Formula::Boolean(_) => (),
|
|
}
|
|
}
|
|
|
|
pub(crate) fn copy_term(term: &crate::Term) -> crate::Term
|
|
{
|
|
use crate::Term;
|
|
|
|
match term
|
|
{
|
|
Term::BinaryOperation(binary_operation) =>
|
|
Term::binary_operation(binary_operation.operator,
|
|
Box::new(copy_term(&binary_operation.left)),
|
|
Box::new(copy_term(&binary_operation.right))),
|
|
Term::Boolean(value) => Term::boolean(*value),
|
|
Term::Function(function) => Term::function(std::rc::Rc::clone(&function.declaration),
|
|
function.arguments.iter().map(|argument| copy_term(argument)).collect()),
|
|
Term::Integer(value) => Term::integer(*value),
|
|
Term::SpecialInteger(value) => Term::special_integer(*value),
|
|
Term::String(value) => Term::string(value.clone()),
|
|
Term::UnaryOperation(unary_operation) => Term::unary_operation(unary_operation.operator,
|
|
Box::new(copy_term(&unary_operation.argument))),
|
|
Term::Variable(variable) => Term::variable(std::rc::Rc::clone(&variable.declaration)),
|
|
}
|
|
}
|
|
|
|
fn copy_quantified_formula(quantified_expression: &crate::QuantifiedFormula)
|
|
-> crate::QuantifiedFormula
|
|
{
|
|
let copy_parameters =
|
|
quantified_expression.parameters.iter()
|
|
// TODO: check correctness of clone implementation
|
|
.map(|x| x.clone())
|
|
.collect();
|
|
let copy_parameters = std::rc::Rc::new(copy_parameters);
|
|
|
|
let mut copy_argument = copy_formula(&quantified_expression.argument);
|
|
|
|
replace_variables_in_formula(&mut copy_argument, &quantified_expression.parameters,
|
|
©_parameters);
|
|
|
|
crate::QuantifiedFormula::new(copy_parameters, Box::new(copy_argument))
|
|
}
|
|
|
|
pub(crate) fn copy_formula(formula: &crate::Formula) -> crate::Formula
|
|
{
|
|
use crate::Formula;
|
|
|
|
match formula
|
|
{
|
|
Formula::And(arguments) =>
|
|
Formula::and(arguments.iter().map(|argument| copy_formula(argument)).collect()),
|
|
Formula::Boolean(value) => Formula::boolean(*value),
|
|
Formula::Compare(compare) =>
|
|
Formula::compare(compare.operator, Box::new(copy_term(&compare.left)),
|
|
Box::new(copy_term(&compare.right))),
|
|
Formula::Exists(quantified_formula) =>
|
|
Formula::Exists(copy_quantified_formula(quantified_formula)),
|
|
Formula::ForAll(quantified_formula) =>
|
|
Formula::ForAll(copy_quantified_formula(quantified_formula)),
|
|
Formula::IfAndOnlyIf(arguments) =>
|
|
Formula::if_and_only_if(
|
|
arguments.iter().map(|argument| copy_formula(argument)).collect()),
|
|
Formula::Implies(implies) =>
|
|
Formula::implies(implies.direction, Box::new(copy_formula(&implies.antecedent)),
|
|
Box::new(copy_formula(&implies.implication))),
|
|
Formula::Not(argument) => Formula::not(Box::new(copy_formula(&argument))),
|
|
Formula::Or(arguments) =>
|
|
Formula::or(arguments.iter().map(|argument| copy_formula(argument)).collect()),
|
|
Formula::Predicate(predicate) =>
|
|
Formula::predicate(std::rc::Rc::clone(&predicate.declaration),
|
|
predicate.arguments.iter().map(|argument| copy_term(argument)).collect()),
|
|
}
|
|
}
|