247 lines
6.3 KiB
Rust
247 lines
6.3 KiB
Rust
struct IDs
|
|
{
|
|
program_variable_id: usize,
|
|
integer_variable_id: usize,
|
|
}
|
|
|
|
impl IDs
|
|
{
|
|
pub fn new() -> Self
|
|
{
|
|
Self
|
|
{
|
|
program_variable_id: 1,
|
|
integer_variable_id: 1,
|
|
}
|
|
}
|
|
}
|
|
|
|
fn reset_variable_name(variable_declaration: &crate::VariableDeclaration)
|
|
{
|
|
let domain = match variable_declaration.domain()
|
|
{
|
|
Ok(domain) => domain,
|
|
Err(_) => unreachable!("all variable domains should be assigned at this point"),
|
|
};
|
|
|
|
let ref mut variable_name = *variable_declaration.name.borrow_mut();
|
|
|
|
match variable_name
|
|
{
|
|
crate::VariableName::Generated(ref mut generated_variable_name) =>
|
|
generated_variable_name.id = None,
|
|
crate::VariableName::UserDefined(_) =>
|
|
*variable_name = crate::VariableName::Generated(
|
|
crate::GeneratedVariableName
|
|
{
|
|
domain,
|
|
id: None,
|
|
}),
|
|
}
|
|
}
|
|
|
|
fn reset_variable_names_in_term(term: &mut crate::Term)
|
|
{
|
|
use foliage::Term;
|
|
|
|
match term
|
|
{
|
|
Term::BinaryOperation(ref mut binary_operation) =>
|
|
{
|
|
reset_variable_names_in_term(&mut *binary_operation.left);
|
|
reset_variable_names_in_term(&mut *binary_operation.right);
|
|
},
|
|
Term::Boolean(_)
|
|
| Term::Integer(_)
|
|
| Term::SpecialInteger(_)
|
|
| Term::String(_) => (),
|
|
Term::Function(ref mut function) =>
|
|
for mut argument in &mut function.arguments
|
|
{
|
|
reset_variable_names_in_term(&mut argument);
|
|
},
|
|
Term::UnaryOperation(ref mut unary_operation) =>
|
|
reset_variable_names_in_term(&mut *unary_operation.argument),
|
|
Term::Variable(ref mut variable) => reset_variable_name(&variable.declaration),
|
|
}
|
|
}
|
|
|
|
fn reset_variable_names_in_formula(formula: &mut crate::Formula)
|
|
{
|
|
use foliage::Formula;
|
|
|
|
match formula
|
|
{
|
|
Formula::And(ref mut arguments)
|
|
| Formula::IfAndOnlyIf(ref mut arguments)
|
|
| Formula::Or(ref mut arguments) =>
|
|
for argument in arguments
|
|
{
|
|
reset_variable_names_in_formula(argument);
|
|
},
|
|
Formula::Boolean(_) => (),
|
|
Formula::Compare(ref mut compare) =>
|
|
{
|
|
reset_variable_names_in_term(&mut *compare.left);
|
|
reset_variable_names_in_term(&mut *compare.right);
|
|
},
|
|
Formula::Exists(ref mut quantified_formula)
|
|
| Formula::ForAll(ref mut quantified_formula) =>
|
|
{
|
|
for ref parameter in &*quantified_formula.parameters
|
|
{
|
|
reset_variable_name(¶meter);
|
|
}
|
|
|
|
reset_variable_names_in_formula(&mut *quantified_formula.argument);
|
|
},
|
|
Formula::Implies(ref mut implies) =>
|
|
{
|
|
reset_variable_names_in_formula(&mut *implies.antecedent);
|
|
reset_variable_names_in_formula(&mut *implies.implication);
|
|
},
|
|
Formula::Not(ref mut argument) => reset_variable_names_in_formula(argument),
|
|
Formula::Predicate(ref mut predicate) =>
|
|
for mut argument in &mut predicate.arguments
|
|
{
|
|
reset_variable_names_in_term(&mut argument);
|
|
},
|
|
}
|
|
}
|
|
|
|
fn set_variable_name(variable_declaration: &crate::VariableDeclaration, ids: &mut IDs)
|
|
{
|
|
match *variable_declaration.name.borrow_mut()
|
|
{
|
|
crate::VariableName::Generated(ref mut generated_variable_name) =>
|
|
{
|
|
if generated_variable_name.id.is_some()
|
|
{
|
|
return;
|
|
}
|
|
|
|
match generated_variable_name.domain
|
|
{
|
|
crate::Domain::Program =>
|
|
{
|
|
generated_variable_name.id = Some(ids.program_variable_id);
|
|
ids.program_variable_id += 1;
|
|
},
|
|
crate::Domain::Integer =>
|
|
{
|
|
generated_variable_name.id = Some(ids.integer_variable_id);
|
|
ids.integer_variable_id += 1;
|
|
},
|
|
}
|
|
},
|
|
crate::VariableName::UserDefined(_) => (),
|
|
}
|
|
}
|
|
|
|
fn set_variable_names_in_term(term: &mut crate::Term, ids: &mut IDs)
|
|
{
|
|
use foliage::Term;
|
|
|
|
match term
|
|
{
|
|
Term::BinaryOperation(ref mut binary_operation) =>
|
|
{
|
|
set_variable_names_in_term(&mut *binary_operation.left, ids);
|
|
set_variable_names_in_term(&mut *binary_operation.right, ids);
|
|
},
|
|
Term::Boolean(_)
|
|
| Term::Integer(_)
|
|
| Term::SpecialInteger(_)
|
|
| Term::String(_) => (),
|
|
Term::Function(ref mut function) =>
|
|
for mut argument in &mut function.arguments
|
|
{
|
|
set_variable_names_in_term(&mut argument, ids);
|
|
},
|
|
Term::UnaryOperation(ref mut unary_operation) =>
|
|
set_variable_names_in_term(&mut *unary_operation.argument, ids),
|
|
Term::Variable(ref mut variable) => set_variable_name(&variable.declaration, ids),
|
|
}
|
|
}
|
|
|
|
fn set_variable_names_in_formula(formula: &mut crate::Formula, ids: &mut IDs)
|
|
{
|
|
use foliage::Formula;
|
|
|
|
match formula
|
|
{
|
|
Formula::And(ref mut arguments)
|
|
| Formula::IfAndOnlyIf(ref mut arguments)
|
|
| Formula::Or(ref mut arguments) =>
|
|
for argument in arguments
|
|
{
|
|
set_variable_names_in_formula(argument, ids);
|
|
},
|
|
Formula::Boolean(_) => (),
|
|
Formula::Compare(ref mut compare) =>
|
|
{
|
|
set_variable_names_in_term(&mut *compare.left, ids);
|
|
set_variable_names_in_term(&mut *compare.right, ids);
|
|
},
|
|
Formula::Exists(ref mut quantified_formula)
|
|
| Formula::ForAll(ref mut quantified_formula) =>
|
|
{
|
|
for ref parameter in &*quantified_formula.parameters
|
|
{
|
|
set_variable_name(¶meter, ids);
|
|
}
|
|
|
|
set_variable_names_in_formula(&mut *quantified_formula.argument, ids);
|
|
},
|
|
Formula::Implies(ref mut implies) =>
|
|
match implies.direction
|
|
{
|
|
foliage::ImplicationDirection::LeftToRight =>
|
|
{
|
|
set_variable_names_in_formula(&mut *implies.antecedent, ids);
|
|
set_variable_names_in_formula(&mut *implies.implication, ids);
|
|
},
|
|
foliage::ImplicationDirection::RightToLeft =>
|
|
{
|
|
set_variable_names_in_formula(&mut *implies.implication, ids);
|
|
set_variable_names_in_formula(&mut *implies.antecedent, ids);
|
|
},
|
|
},
|
|
Formula::Not(ref mut argument) => set_variable_names_in_formula(argument, ids),
|
|
Formula::Predicate(ref mut predicate) =>
|
|
for mut argument in &mut predicate.arguments
|
|
{
|
|
set_variable_names_in_term(&mut argument, ids);
|
|
},
|
|
}
|
|
}
|
|
|
|
pub(crate) fn autoname_variables(formula: &mut crate::Formula)
|
|
{
|
|
// TODO: refactor, this is a bit hacky
|
|
reset_variable_names_in_formula(formula);
|
|
|
|
let mut ids = IDs::new();
|
|
|
|
set_variable_names_in_formula(formula, &mut ids);
|
|
|
|
// If there only exists exactly one program variable (which incremented the ID from 1 to 2),
|
|
// give it the special ID 0 on the second run
|
|
ids.program_variable_id = match ids.program_variable_id
|
|
{
|
|
2 => 0,
|
|
_ => 1,
|
|
};
|
|
|
|
// If there only exists exactly one integer variable (which incremented the ID from 1 to 2),
|
|
// give it the special ID 0 on the second run
|
|
ids.integer_variable_id = match ids.integer_variable_id
|
|
{
|
|
2 => 0,
|
|
_ => 1,
|
|
};
|
|
|
|
reset_variable_names_in_formula(formula);
|
|
set_variable_names_in_formula(formula, &mut ids);
|
|
}
|