Use custom foliage flavor
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.
This commit is contained in:
parent
b62c379b97
commit
81ddfd450a
361
src/ast.rs
Normal file
361
src/ast.rs
Normal file
@ -0,0 +1,361 @@
|
||||
pub struct FoliageFlavor;
|
||||
|
||||
pub struct FunctionDeclaration
|
||||
{
|
||||
pub declaration: foliage::FunctionDeclaration,
|
||||
pub domain: std::cell::RefCell<crate::Domain>,
|
||||
pub is_input: std::cell::RefCell<bool>,
|
||||
}
|
||||
|
||||
impl FunctionDeclaration
|
||||
{
|
||||
pub fn is_built_in(&self) -> bool
|
||||
{
|
||||
use foliage::flavor::FunctionDeclaration;
|
||||
|
||||
self.declaration.name.starts_with("f__") && self.declaration.name.ends_with("__")
|
||||
}
|
||||
}
|
||||
|
||||
impl std::cmp::PartialEq for FunctionDeclaration
|
||||
{
|
||||
#[inline(always)]
|
||||
fn eq(&self, other: &Self) -> bool
|
||||
{
|
||||
self.declaration.eq(&other.declaration)
|
||||
}
|
||||
}
|
||||
|
||||
impl std::cmp::Eq for FunctionDeclaration
|
||||
{
|
||||
}
|
||||
|
||||
impl std::cmp::PartialOrd for FunctionDeclaration
|
||||
{
|
||||
#[inline(always)]
|
||||
fn partial_cmp(&self, other: &FunctionDeclaration) -> Option<std::cmp::Ordering>
|
||||
{
|
||||
self.declaration.partial_cmp(&other.declaration)
|
||||
}
|
||||
}
|
||||
|
||||
impl std::cmp::Ord for FunctionDeclaration
|
||||
{
|
||||
#[inline(always)]
|
||||
fn cmp(&self, other: &FunctionDeclaration) -> std::cmp::Ordering
|
||||
{
|
||||
self.declaration.cmp(&other.declaration)
|
||||
}
|
||||
}
|
||||
|
||||
impl std::hash::Hash for FunctionDeclaration
|
||||
{
|
||||
#[inline(always)]
|
||||
fn hash<H: std::hash::Hasher>(&self, state: &mut H)
|
||||
{
|
||||
self.declaration.hash(state)
|
||||
}
|
||||
}
|
||||
|
||||
impl foliage::flavor::FunctionDeclaration for FunctionDeclaration
|
||||
{
|
||||
fn new(name: String, arity: usize) -> Self
|
||||
{
|
||||
Self
|
||||
{
|
||||
declaration: foliage::FunctionDeclaration::new(name, arity),
|
||||
domain: std::cell::RefCell::new(crate::Domain::Program),
|
||||
is_input: std::cell::RefCell::new(false),
|
||||
}
|
||||
}
|
||||
|
||||
fn display_name(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result
|
||||
{
|
||||
self.declaration.display_name(formatter)
|
||||
}
|
||||
|
||||
fn arity(&self) -> usize
|
||||
{
|
||||
self.declaration.arity
|
||||
}
|
||||
|
||||
fn matches_signature(&self, other_name: &str, other_arity: usize) -> bool
|
||||
{
|
||||
self.declaration.matches_signature(other_name, other_arity)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct PredicateDeclaration
|
||||
{
|
||||
pub declaration: foliage::PredicateDeclaration,
|
||||
pub is_input: std::cell::RefCell<bool>,
|
||||
pub is_output: std::cell::RefCell<bool>,
|
||||
}
|
||||
|
||||
impl PredicateDeclaration
|
||||
{
|
||||
pub fn tptp_statement_name(&self) -> String
|
||||
{
|
||||
format!("{}_{}", self.declaration.name, self.declaration.arity)
|
||||
}
|
||||
|
||||
pub fn is_built_in(&self) -> bool
|
||||
{
|
||||
self.declaration.name.starts_with("p__") && self.declaration.name.ends_with("__")
|
||||
}
|
||||
}
|
||||
|
||||
impl std::cmp::PartialEq for PredicateDeclaration
|
||||
{
|
||||
#[inline(always)]
|
||||
fn eq(&self, other: &Self) -> bool
|
||||
{
|
||||
self.declaration.eq(&other.declaration)
|
||||
}
|
||||
}
|
||||
|
||||
impl std::cmp::Eq for PredicateDeclaration
|
||||
{
|
||||
}
|
||||
|
||||
impl std::cmp::PartialOrd for PredicateDeclaration
|
||||
{
|
||||
#[inline(always)]
|
||||
fn partial_cmp(&self, other: &PredicateDeclaration) -> Option<std::cmp::Ordering>
|
||||
{
|
||||
self.declaration.partial_cmp(&other.declaration)
|
||||
}
|
||||
}
|
||||
|
||||
impl std::cmp::Ord for PredicateDeclaration
|
||||
{
|
||||
#[inline(always)]
|
||||
fn cmp(&self, other: &PredicateDeclaration) -> std::cmp::Ordering
|
||||
{
|
||||
self.declaration.cmp(&other.declaration)
|
||||
}
|
||||
}
|
||||
|
||||
impl std::hash::Hash for PredicateDeclaration
|
||||
{
|
||||
#[inline(always)]
|
||||
fn hash<H: std::hash::Hasher>(&self, state: &mut H)
|
||||
{
|
||||
self.declaration.hash(state)
|
||||
}
|
||||
}
|
||||
|
||||
impl foliage::flavor::PredicateDeclaration for PredicateDeclaration
|
||||
{
|
||||
fn new(name: String, arity: usize) -> Self
|
||||
{
|
||||
Self
|
||||
{
|
||||
declaration: foliage::PredicateDeclaration::new(name, arity),
|
||||
is_input: std::cell::RefCell::new(false),
|
||||
is_output: std::cell::RefCell::new(false),
|
||||
}
|
||||
}
|
||||
|
||||
fn display_name(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result
|
||||
{
|
||||
self.declaration.display_name(formatter)
|
||||
}
|
||||
|
||||
fn arity(&self) -> usize
|
||||
{
|
||||
self.declaration.arity
|
||||
}
|
||||
|
||||
fn matches_signature(&self, other_name: &str, other_arity: usize) -> bool
|
||||
{
|
||||
self.declaration.matches_signature(other_name, other_arity)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct GeneratedVariableName
|
||||
{
|
||||
pub domain: crate::Domain,
|
||||
pub id: Option<usize>,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub enum VariableName
|
||||
{
|
||||
UserDefined(String),
|
||||
Generated(GeneratedVariableName),
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct VariableDeclaration
|
||||
{
|
||||
pub name: std::cell::RefCell<VariableName>,
|
||||
}
|
||||
|
||||
impl VariableDeclaration
|
||||
{
|
||||
pub fn new_generated(domain: crate::Domain) -> Self
|
||||
{
|
||||
let generated_variable_name = GeneratedVariableName
|
||||
{
|
||||
domain,
|
||||
id: None,
|
||||
};
|
||||
|
||||
Self
|
||||
{
|
||||
name: std::cell::RefCell::new(VariableName::Generated(generated_variable_name)),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn domain(&self) -> Result<crate::Domain, crate::Error>
|
||||
{
|
||||
match *self.name.borrow()
|
||||
{
|
||||
VariableName::UserDefined(ref name) =>
|
||||
{
|
||||
let mut name_characters = name.chars();
|
||||
|
||||
loop
|
||||
{
|
||||
match name_characters.next()
|
||||
{
|
||||
Some('I')
|
||||
| Some('J')
|
||||
| Some('K')
|
||||
| Some('L')
|
||||
| Some('M')
|
||||
| Some('N') => return Ok(crate::Domain::Integer),
|
||||
Some('X')
|
||||
| Some('Y')
|
||||
| Some('Z') => return Ok(crate::Domain::Program),
|
||||
Some('_') => continue,
|
||||
_ => return Err(
|
||||
crate::Error::new_variable_name_not_allowed(name.to_string())),
|
||||
}
|
||||
}
|
||||
},
|
||||
VariableName::Generated(ref generated_variable_name) =>
|
||||
Ok(generated_variable_name.domain),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::cmp::PartialEq for VariableDeclaration
|
||||
{
|
||||
#[inline(always)]
|
||||
fn eq(&self, other: &Self) -> bool
|
||||
{
|
||||
let l = self as *const Self;
|
||||
let r = other as *const Self;
|
||||
|
||||
l.eq(&r)
|
||||
}
|
||||
}
|
||||
|
||||
impl std::cmp::Eq for VariableDeclaration
|
||||
{
|
||||
}
|
||||
|
||||
impl std::cmp::PartialOrd for VariableDeclaration
|
||||
{
|
||||
#[inline(always)]
|
||||
fn partial_cmp(&self, other: &VariableDeclaration) -> Option<std::cmp::Ordering>
|
||||
{
|
||||
let l = self as *const VariableDeclaration;
|
||||
let r = other as *const VariableDeclaration;
|
||||
|
||||
l.partial_cmp(&r)
|
||||
}
|
||||
}
|
||||
|
||||
impl std::cmp::Ord for VariableDeclaration
|
||||
{
|
||||
#[inline(always)]
|
||||
fn cmp(&self, other: &VariableDeclaration) -> std::cmp::Ordering
|
||||
{
|
||||
let l = self as *const VariableDeclaration;
|
||||
let r = other as *const VariableDeclaration;
|
||||
|
||||
l.cmp(&r)
|
||||
}
|
||||
}
|
||||
|
||||
impl std::hash::Hash for VariableDeclaration
|
||||
{
|
||||
#[inline(always)]
|
||||
fn hash<H: std::hash::Hasher>(&self, state: &mut H)
|
||||
{
|
||||
let p = self as *const VariableDeclaration;
|
||||
|
||||
p.hash(state);
|
||||
}
|
||||
}
|
||||
|
||||
impl foliage::flavor::VariableDeclaration for VariableDeclaration
|
||||
{
|
||||
fn new(name: String) -> Self
|
||||
{
|
||||
Self
|
||||
{
|
||||
name: std::cell::RefCell::new(VariableName::UserDefined(name)),
|
||||
}
|
||||
}
|
||||
|
||||
fn display_name(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result
|
||||
{
|
||||
match *self.name.borrow()
|
||||
{
|
||||
VariableName::UserDefined(ref name) => write!(formatter, "{}", name),
|
||||
VariableName::Generated(ref generated_variable_name) =>
|
||||
{
|
||||
let variable_name_prefix = match generated_variable_name.domain
|
||||
{
|
||||
crate::Domain::Program => "X",
|
||||
crate::Domain::Integer => "N",
|
||||
};
|
||||
|
||||
let variable_id = match generated_variable_name.id
|
||||
{
|
||||
Some(id) => id,
|
||||
None => unreachable!("all variable IDs should be assigned at this point"),
|
||||
};
|
||||
|
||||
write!(formatter, "{}{}", variable_name_prefix, variable_id + 1)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn matches_name(&self, other_name: &str) -> bool
|
||||
{
|
||||
match *self.name.borrow()
|
||||
{
|
||||
VariableName::UserDefined(ref name) => name == other_name,
|
||||
// Generated variable declarations never match user-defined variables by name
|
||||
VariableName::Generated(_) => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl foliage::flavor::Flavor for FoliageFlavor
|
||||
{
|
||||
type FunctionDeclaration = FunctionDeclaration;
|
||||
type PredicateDeclaration = PredicateDeclaration;
|
||||
type VariableDeclaration = VariableDeclaration;
|
||||
}
|
||||
|
||||
pub type BinaryOperation = foliage::BinaryOperation<FoliageFlavor>;
|
||||
pub type Formula = foliage::Formula<FoliageFlavor>;
|
||||
pub type Formulas = foliage::Formulas<FoliageFlavor>;
|
||||
pub type FunctionDeclarations = foliage::FunctionDeclarations<FoliageFlavor>;
|
||||
pub type OpenFormula = foliage::OpenFormula<FoliageFlavor>;
|
||||
pub type Predicate = foliage::Predicate<FoliageFlavor>;
|
||||
pub type PredicateDeclarations = foliage::PredicateDeclarations<FoliageFlavor>;
|
||||
pub type QuantifiedFormula = foliage::QuantifiedFormula<FoliageFlavor>;
|
||||
pub type Term = foliage::Term<FoliageFlavor>;
|
||||
pub type UnaryOperation = foliage::UnaryOperation<FoliageFlavor>;
|
||||
pub type Variable = foliage::Variable<FoliageFlavor>;
|
||||
pub type VariableDeclarationStackLayer<'p> =
|
||||
foliage::VariableDeclarationStackLayer<'p, FoliageFlavor>;
|
||||
pub type VariableDeclarations = foliage::VariableDeclarations<FoliageFlavor>;
|
40
src/error.rs
40
src/error.rs
@ -1,3 +1,5 @@
|
||||
use foliage::flavor::VariableDeclaration as _;
|
||||
|
||||
pub type Source = Box<dyn std::error::Error>;
|
||||
|
||||
pub enum Kind
|
||||
@ -21,10 +23,10 @@ pub enum Kind
|
||||
UnknownProofDirection(String),
|
||||
UnknownDomainIdentifier(String),
|
||||
VariableNameNotAllowed(String),
|
||||
FormulaNotClosed(std::rc::Rc<foliage::VariableDeclarations>),
|
||||
NoCompletedDefinitionFound(std::rc::Rc<foliage::PredicateDeclaration>),
|
||||
CannotHidePredicate(std::rc::Rc<foliage::PredicateDeclaration>),
|
||||
PredicateShouldNotOccurInSpecification(std::rc::Rc<foliage::PredicateDeclaration>),
|
||||
FormulaNotClosed(std::rc::Rc<crate::VariableDeclarations>),
|
||||
NoCompletedDefinitionFound(std::rc::Rc<crate::PredicateDeclaration>),
|
||||
CannotHidePredicate(std::rc::Rc<crate::PredicateDeclaration>),
|
||||
PredicateShouldNotOccurInSpecification(std::rc::Rc<crate::PredicateDeclaration>),
|
||||
WriteTPTPProgram,
|
||||
RunVampire,
|
||||
// TODO: rename to something Vampire-specific
|
||||
@ -146,28 +148,28 @@ impl Error
|
||||
Self::new(Kind::VariableNameNotAllowed(variable_name))
|
||||
}
|
||||
|
||||
pub(crate) fn new_formula_not_closed(free_variables: std::rc::Rc<foliage::VariableDeclarations>)
|
||||
pub(crate) fn new_formula_not_closed(free_variables: std::rc::Rc<crate::VariableDeclarations>)
|
||||
-> Self
|
||||
{
|
||||
Self::new(Kind::FormulaNotClosed(free_variables))
|
||||
}
|
||||
|
||||
pub(crate) fn new_no_completed_definition_found(
|
||||
predicate_declaration: std::rc::Rc<foliage::PredicateDeclaration>)
|
||||
predicate_declaration: std::rc::Rc<crate::PredicateDeclaration>)
|
||||
-> Self
|
||||
{
|
||||
Self::new(Kind::NoCompletedDefinitionFound(predicate_declaration))
|
||||
}
|
||||
|
||||
pub(crate) fn new_cannot_hide_predicate(
|
||||
predicate_declaration: std::rc::Rc<foliage::PredicateDeclaration>)
|
||||
predicate_declaration: std::rc::Rc<crate::PredicateDeclaration>)
|
||||
-> Self
|
||||
{
|
||||
Self::new(Kind::CannotHidePredicate(predicate_declaration))
|
||||
}
|
||||
|
||||
pub(crate) fn new_predicate_should_not_occur_in_specification(
|
||||
predicate_declaration: std::rc::Rc<foliage::PredicateDeclaration>)
|
||||
predicate_declaration: std::rc::Rc<crate::PredicateDeclaration>)
|
||||
-> Self
|
||||
{
|
||||
Self::new(Kind::PredicateShouldNotOccurInSpecification(predicate_declaration))
|
||||
@ -240,25 +242,29 @@ impl std::fmt::Debug for Error
|
||||
Kind::WriteTPTPProgram => write!(formatter, "error writing TPTP program"),
|
||||
Kind::FormulaNotClosed(free_variable_declarations) =>
|
||||
{
|
||||
let free_variable_names = free_variable_declarations
|
||||
.iter()
|
||||
.map(|variable_declaration| &variable_declaration.name);
|
||||
write!(formatter, "formula may not contain free variables (free variables in this formula: ")?;
|
||||
|
||||
let free_variable_names_output = itertools::join(free_variable_names, ", ");
|
||||
let mut separator = "";
|
||||
|
||||
write!(formatter, "formula may not contain free variables (free variables in this formula: {})",
|
||||
free_variable_names_output)
|
||||
for free_variable_declaration in &**free_variable_declarations
|
||||
{
|
||||
write!(formatter, "{}", separator)?;
|
||||
free_variable_declaration.display_name(formatter)?;
|
||||
separator = ", ";
|
||||
}
|
||||
|
||||
write!(formatter, ")")
|
||||
},
|
||||
Kind::NoCompletedDefinitionFound(ref predicate_declaration) =>
|
||||
write!(formatter, "no completed definition found for {}", predicate_declaration),
|
||||
write!(formatter, "no completed definition found for {}", predicate_declaration.declaration),
|
||||
Kind::CannotHidePredicate(ref predicate_declaration) =>
|
||||
write!(formatter,
|
||||
"cannot hide predicate {} (the completed definition transitively depends on itself)",
|
||||
predicate_declaration),
|
||||
predicate_declaration.declaration),
|
||||
Kind::PredicateShouldNotOccurInSpecification(ref predicate_declaration) =>
|
||||
write!(formatter,
|
||||
"{} should not occur in specification because it’s a private predicate (consider declaring it an input or output predicate)",
|
||||
predicate_declaration),
|
||||
predicate_declaration.declaration),
|
||||
Kind::RunVampire => write!(formatter, "could not run Vampire"),
|
||||
Kind::ProveProgram(exit_code, ref stdout, ref stderr) =>
|
||||
{
|
||||
|
@ -1,96 +1,8 @@
|
||||
// TODO: refactor
|
||||
fn term_assign_variable_declaration_domains<D>(term: &foliage::Term, declarations: &D)
|
||||
-> Result<(), crate::Error>
|
||||
where
|
||||
D: crate::traits::AssignVariableDeclarationDomain,
|
||||
{
|
||||
match term
|
||||
{
|
||||
foliage::Term::BinaryOperation(binary_operation) =>
|
||||
{
|
||||
term_assign_variable_declaration_domains(&binary_operation.left, declarations)?;
|
||||
term_assign_variable_declaration_domains(&binary_operation.right, declarations)?;
|
||||
},
|
||||
foliage::Term::Function(function) =>
|
||||
for argument in &function.arguments
|
||||
{
|
||||
term_assign_variable_declaration_domains(&argument, declarations)?;
|
||||
},
|
||||
foliage::Term::UnaryOperation(unary_operation) =>
|
||||
term_assign_variable_declaration_domains(&unary_operation.argument, declarations)?,
|
||||
foliage::Term::Variable(variable) =>
|
||||
{
|
||||
let domain = match variable.declaration.name.chars().next()
|
||||
{
|
||||
Some('X')
|
||||
| Some('Y')
|
||||
| Some('Z') => crate::Domain::Program,
|
||||
Some('I')
|
||||
| Some('J')
|
||||
| Some('K')
|
||||
| Some('L')
|
||||
| Some('M')
|
||||
| Some('N') => crate::Domain::Integer,
|
||||
Some(_) => return Err(
|
||||
crate::Error::new_variable_name_not_allowed(variable.declaration.name.clone())),
|
||||
None => unreachable!(),
|
||||
};
|
||||
|
||||
declarations.assign_variable_declaration_domain(&variable.declaration, domain);
|
||||
},
|
||||
_ => (),
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn formula_assign_variable_declaration_domains<D>(formula: &foliage::Formula, declarations: &D)
|
||||
-> Result<(), crate::Error>
|
||||
where
|
||||
D: crate::traits::AssignVariableDeclarationDomain,
|
||||
{
|
||||
match formula
|
||||
{
|
||||
foliage::Formula::And(arguments)
|
||||
| foliage::Formula::Or(arguments)
|
||||
| foliage::Formula::IfAndOnlyIf(arguments) =>
|
||||
for argument in arguments
|
||||
{
|
||||
formula_assign_variable_declaration_domains(&argument, declarations)?;
|
||||
},
|
||||
foliage::Formula::Compare(compare) =>
|
||||
{
|
||||
term_assign_variable_declaration_domains(&compare.left, declarations)?;
|
||||
term_assign_variable_declaration_domains(&compare.right, declarations)?;
|
||||
},
|
||||
foliage::Formula::Exists(quantified_formula)
|
||||
| foliage::Formula::ForAll(quantified_formula) =>
|
||||
formula_assign_variable_declaration_domains(&quantified_formula.argument,
|
||||
declarations)?,
|
||||
foliage::Formula::Implies(implies) =>
|
||||
{
|
||||
formula_assign_variable_declaration_domains(&implies.antecedent, declarations)?;
|
||||
formula_assign_variable_declaration_domains(&implies.implication, declarations)?;
|
||||
}
|
||||
foliage::Formula::Not(argument) =>
|
||||
formula_assign_variable_declaration_domains(&argument, declarations)?,
|
||||
foliage::Formula::Predicate(predicate) =>
|
||||
for argument in &predicate.arguments
|
||||
{
|
||||
term_assign_variable_declaration_domains(&argument, declarations)?;
|
||||
},
|
||||
_ => (),
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn open_formula<'i, D>(input: &'i str, declarations: &D)
|
||||
-> Result<(foliage::OpenFormula, &'i str), crate::Error>
|
||||
-> Result<(crate::OpenFormula, &'i str), crate::Error>
|
||||
where
|
||||
D: foliage::FindOrCreateFunctionDeclaration
|
||||
+ foliage::FindOrCreatePredicateDeclaration
|
||||
+ crate::traits::AssignVariableDeclarationDomain,
|
||||
D: foliage::FindOrCreateFunctionDeclaration<crate::FoliageFlavor>
|
||||
+ foliage::FindOrCreatePredicateDeclaration<crate::FoliageFlavor>
|
||||
{
|
||||
let terminator_position = match input.find('.')
|
||||
{
|
||||
@ -106,9 +18,7 @@ where
|
||||
let open_formula = foliage::parse::formula(formula_input, declarations)
|
||||
.map_err(|error| crate::Error::new_parse_formula(error))?;
|
||||
|
||||
formula_assign_variable_declaration_domains(&open_formula.formula, declarations)?;
|
||||
|
||||
let open_formula = foliage::OpenFormula
|
||||
let open_formula = crate::OpenFormula
|
||||
{
|
||||
free_variable_declarations: open_formula.free_variable_declarations,
|
||||
formula: open_formula.formula,
|
||||
@ -118,11 +28,10 @@ where
|
||||
}
|
||||
|
||||
fn formula<'i, D>(mut input: &'i str, declarations: &D)
|
||||
-> Result<(foliage::Formula, &'i str), crate::Error>
|
||||
-> Result<(crate::Formula, &'i str), crate::Error>
|
||||
where
|
||||
D: foliage::FindOrCreateFunctionDeclaration
|
||||
+ foliage::FindOrCreatePredicateDeclaration
|
||||
+ crate::traits::AssignVariableDeclarationDomain,
|
||||
D: foliage::FindOrCreateFunctionDeclaration<crate::FoliageFlavor>
|
||||
+ foliage::FindOrCreatePredicateDeclaration<crate::FoliageFlavor>
|
||||
{
|
||||
let (open_formula, remaining_input) = open_formula(input, declarations)?;
|
||||
|
||||
@ -137,7 +46,7 @@ where
|
||||
}
|
||||
|
||||
fn formula_statement_body<'i>(mut input: &'i str, problem: &crate::Problem)
|
||||
-> Result<(foliage::Formula, &'i str), crate::Error>
|
||||
-> Result<(crate::Formula, &'i str), crate::Error>
|
||||
{
|
||||
input = foliage::parse::tokens::trim_start(input);
|
||||
|
||||
@ -257,15 +166,12 @@ fn input_statement_body<'i>(mut input: &'i str, problem: &crate::Problem)
|
||||
{
|
||||
input = remaining_input;
|
||||
|
||||
let mut input_predicate_declarations =
|
||||
problem.input_predicate_declarations.borrow_mut();
|
||||
|
||||
use foliage::FindOrCreatePredicateDeclaration as _;
|
||||
|
||||
let predicate_declaration =
|
||||
problem.find_or_create_predicate_declaration(constant_or_predicate_name, arity);
|
||||
|
||||
input_predicate_declarations.insert(predicate_declaration);
|
||||
*predicate_declaration.is_input.borrow_mut() = true;
|
||||
}
|
||||
// Parse input constant specifiers
|
||||
else
|
||||
@ -279,20 +185,13 @@ fn input_statement_body<'i>(mut input: &'i str, problem: &crate::Problem)
|
||||
|
||||
input = remaining_input;
|
||||
|
||||
let mut input_constant_declarations =
|
||||
problem.input_constant_declarations.borrow_mut();
|
||||
|
||||
use foliage::FindOrCreateFunctionDeclaration as _;
|
||||
|
||||
let constant_declaration =
|
||||
problem.find_or_create_function_declaration(constant_or_predicate_name, 0);
|
||||
|
||||
input_constant_declarations.insert(std::rc::Rc::clone(&constant_declaration));
|
||||
|
||||
let mut input_constant_declaration_domains =
|
||||
problem.input_constant_declaration_domains.borrow_mut();
|
||||
|
||||
input_constant_declaration_domains.insert(constant_declaration, domain);
|
||||
*constant_declaration.is_input.borrow_mut() = true;
|
||||
*constant_declaration.domain.borrow_mut() = domain;
|
||||
}
|
||||
|
||||
let mut input_characters = input.chars();
|
||||
@ -337,15 +236,12 @@ fn output_statement_body<'i>(mut input: &'i str, problem: &crate::Problem)
|
||||
{
|
||||
input = remaining_input;
|
||||
|
||||
let mut output_predicate_declarations =
|
||||
problem.output_predicate_declarations.borrow_mut();
|
||||
|
||||
use foliage::FindOrCreatePredicateDeclaration as _;
|
||||
|
||||
let predicate_declaration =
|
||||
problem.find_or_create_predicate_declaration(constant_or_predicate_name, arity);
|
||||
|
||||
output_predicate_declarations.insert(predicate_declaration);
|
||||
*predicate_declaration.is_output.borrow_mut() = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1,16 +1,17 @@
|
||||
#![feature(trait_alias)]
|
||||
#![feature(vec_remove_item)]
|
||||
|
||||
mod ast;
|
||||
pub mod commands;
|
||||
pub mod error;
|
||||
pub mod input;
|
||||
pub mod output;
|
||||
pub mod problem;
|
||||
pub mod simplify;
|
||||
pub(crate) mod traits;
|
||||
pub mod translate;
|
||||
mod utils;
|
||||
|
||||
pub use crate::ast::*;
|
||||
pub use error::Error;
|
||||
pub use problem::Problem;
|
||||
pub(crate) use simplify::*;
|
||||
|
@ -1,3 +1,6 @@
|
||||
use foliage::flavor::{FunctionDeclaration as _, PredicateDeclaration as _,
|
||||
VariableDeclaration as _};
|
||||
|
||||
pub(crate) struct DomainDisplay
|
||||
{
|
||||
domain: crate::Domain,
|
||||
@ -33,37 +36,22 @@ impl std::fmt::Display for DomainDisplay
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) struct FunctionDeclarationDisplay<'a, 'b, C>
|
||||
where
|
||||
C: crate::traits::InputConstantDeclarationDomain
|
||||
pub(crate) struct FunctionDeclarationDisplay<'a>(&'a crate::FunctionDeclaration);
|
||||
|
||||
pub(crate) fn display_function_declaration<'a>(function_declaration: &'a crate::FunctionDeclaration)
|
||||
-> FunctionDeclarationDisplay<'a>
|
||||
{
|
||||
function_declaration: &'a std::rc::Rc<foliage::FunctionDeclaration>,
|
||||
context: &'b C,
|
||||
FunctionDeclarationDisplay(function_declaration)
|
||||
}
|
||||
|
||||
pub(crate) fn display_function_declaration<'a, 'b, C>(
|
||||
function_declaration: &'a std::rc::Rc<foliage::FunctionDeclaration>, context: &'b C)
|
||||
-> FunctionDeclarationDisplay<'a, 'b, C>
|
||||
where
|
||||
C: crate::traits::InputConstantDeclarationDomain
|
||||
{
|
||||
FunctionDeclarationDisplay
|
||||
{
|
||||
function_declaration,
|
||||
context,
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'b, C> std::fmt::Debug for FunctionDeclarationDisplay<'a, 'b, C>
|
||||
where
|
||||
C: crate::traits::InputConstantDeclarationDomain
|
||||
impl<'a> std::fmt::Debug for FunctionDeclarationDisplay<'a>
|
||||
{
|
||||
fn fmt(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result
|
||||
{
|
||||
write!(formatter, "{}:", self.function_declaration.name)?;
|
||||
self.0.display_name(formatter)?;
|
||||
write!(formatter, ":")?;
|
||||
|
||||
let domain = self.context.input_constant_declaration_domain(self.function_declaration);
|
||||
let domain_identifier = match domain
|
||||
let domain_identifier = match *self.0.domain.borrow()
|
||||
{
|
||||
crate::Domain::Integer => "$int",
|
||||
crate::Domain::Program => "object",
|
||||
@ -71,11 +59,11 @@ where
|
||||
|
||||
let mut separator = "";
|
||||
|
||||
if self.function_declaration.arity > 0
|
||||
if self.0.arity() > 0
|
||||
{
|
||||
write!(formatter, " (")?;
|
||||
|
||||
for _ in 0..self.function_declaration.arity
|
||||
for _ in 0..self.0.arity()
|
||||
{
|
||||
write!(formatter, "{}object", separator)?;
|
||||
separator = " * ";
|
||||
@ -88,9 +76,7 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'b, C> std::fmt::Display for FunctionDeclarationDisplay<'a, 'b, C>
|
||||
where
|
||||
C: crate::traits::InputConstantDeclarationDomain
|
||||
impl<'a> std::fmt::Display for FunctionDeclarationDisplay<'a>
|
||||
{
|
||||
fn fmt(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result
|
||||
{
|
||||
@ -98,10 +84,10 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) struct PredicateDeclarationDisplay<'a>(&'a std::rc::Rc<foliage::PredicateDeclaration>);
|
||||
pub(crate) struct PredicateDeclarationDisplay<'a>(&'a crate::PredicateDeclaration);
|
||||
|
||||
pub(crate) fn display_predicate_declaration<'a>(
|
||||
predicate_declaration: &'a std::rc::Rc<foliage::PredicateDeclaration>)
|
||||
predicate_declaration: &'a crate::PredicateDeclaration)
|
||||
-> PredicateDeclarationDisplay<'a>
|
||||
{
|
||||
PredicateDeclarationDisplay(predicate_declaration)
|
||||
@ -111,15 +97,16 @@ impl<'a> std::fmt::Debug for PredicateDeclarationDisplay<'a>
|
||||
{
|
||||
fn fmt(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result
|
||||
{
|
||||
write!(formatter, "{}:", self.0.name)?;
|
||||
self.0.display_name(formatter)?;
|
||||
write!(formatter, ":")?;
|
||||
|
||||
let mut separator = "";
|
||||
|
||||
if self.0.arity > 0
|
||||
if self.0.arity() > 0
|
||||
{
|
||||
write!(formatter, " (")?;
|
||||
|
||||
for _ in 0..self.0.arity
|
||||
for _ in 0..self.0.arity()
|
||||
{
|
||||
write!(formatter, "{}object", separator)?;
|
||||
separator = " * ";
|
||||
@ -140,94 +127,20 @@ impl<'a> std::fmt::Display for PredicateDeclarationDisplay<'a>
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) struct VariableDeclarationDisplay<'a, 'b, C>
|
||||
where
|
||||
C: crate::traits::VariableDeclarationDomain
|
||||
+ crate::traits::VariableDeclarationID
|
||||
pub(crate) struct TermDisplay<'a>(&'a crate::Term);
|
||||
|
||||
pub(crate) fn display_term<'a>(term: &'a crate::Term) -> TermDisplay<'a>
|
||||
{
|
||||
variable_declaration: &'a std::rc::Rc<foliage::VariableDeclaration>,
|
||||
context: &'b C,
|
||||
TermDisplay(term)
|
||||
}
|
||||
|
||||
pub(crate) fn display_variable_declaration<'a, 'b, C>(
|
||||
variable_declaration: &'a std::rc::Rc<foliage::VariableDeclaration>, context: &'b C)
|
||||
-> VariableDeclarationDisplay<'a, 'b, C>
|
||||
where
|
||||
C: crate::traits::VariableDeclarationDomain
|
||||
+ crate::traits::VariableDeclarationID
|
||||
{
|
||||
VariableDeclarationDisplay
|
||||
{
|
||||
variable_declaration,
|
||||
context,
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'b, C> std::fmt::Debug for VariableDeclarationDisplay<'a, 'b, C>
|
||||
where
|
||||
C: crate::traits::VariableDeclarationDomain
|
||||
+ crate::traits::VariableDeclarationID
|
||||
impl<'a> std::fmt::Debug for TermDisplay<'a>
|
||||
{
|
||||
fn fmt(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result
|
||||
{
|
||||
let id = self.context.variable_declaration_id(self.variable_declaration);
|
||||
let domain = self.context.variable_declaration_domain(self.variable_declaration)
|
||||
.expect("unspecified variable domain");
|
||||
|
||||
let prefix = match domain
|
||||
{
|
||||
crate::Domain::Integer => "N",
|
||||
crate::Domain::Program => "X",
|
||||
};
|
||||
|
||||
write!(formatter, "{}{}", prefix, id + 1)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'b, C> std::fmt::Display for VariableDeclarationDisplay<'a, 'b, C>
|
||||
where
|
||||
C: crate::traits::VariableDeclarationDomain
|
||||
+ crate::traits::VariableDeclarationID
|
||||
{
|
||||
fn fmt(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result
|
||||
{
|
||||
write!(formatter, "{:?}", &self)
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) struct TermDisplay<'a, 'b, C>
|
||||
{
|
||||
term: &'a foliage::Term,
|
||||
context: &'b C,
|
||||
}
|
||||
|
||||
pub(crate) fn display_term<'a, 'b, C>(term: &'a foliage::Term, context: &'b C)
|
||||
-> TermDisplay<'a, 'b, C>
|
||||
where
|
||||
C: crate::traits::VariableDeclarationDomain
|
||||
+ crate::traits::VariableDeclarationID
|
||||
{
|
||||
TermDisplay
|
||||
{
|
||||
term,
|
||||
context,
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'b, C> std::fmt::Debug for TermDisplay<'a, 'b, C>
|
||||
where
|
||||
C: crate::traits::VariableDeclarationDomain
|
||||
+ crate::traits::VariableDeclarationID
|
||||
{
|
||||
fn fmt(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result
|
||||
{
|
||||
let display_variable_declaration = |variable_declaration|
|
||||
display_variable_declaration(variable_declaration, self.context);
|
||||
let display_term = |term| display_term(term, self.context);
|
||||
|
||||
use foliage::*;
|
||||
|
||||
match &self.term
|
||||
match &self.0
|
||||
{
|
||||
Term::Boolean(true) => write!(formatter, "$true"),
|
||||
Term::Boolean(false) => write!(formatter, "$false"),
|
||||
@ -239,19 +152,19 @@ where
|
||||
false => write!(formatter, "{}", value),
|
||||
},
|
||||
Term::String(_) => panic!("strings not supported in TPTP"),
|
||||
Term::Variable(variable) =>
|
||||
write!(formatter, "{:?}", display_variable_declaration(&variable.declaration)),
|
||||
Term::Variable(variable) => variable.declaration.display_name(formatter),
|
||||
Term::Function(function) =>
|
||||
{
|
||||
write!(formatter, "{}", function.declaration.name)?;
|
||||
function.declaration.display_name(formatter)?;
|
||||
|
||||
assert!(function.declaration.arity == function.arguments.len(),
|
||||
assert!(function.declaration.arity() == function.arguments.len(),
|
||||
"function has a different number of arguments than declared (expected {}, got {})",
|
||||
function.declaration.arity, function.arguments.len());
|
||||
function.declaration.arity(), function.arguments.len());
|
||||
|
||||
if function.arguments.len() > 0
|
||||
{
|
||||
write!(formatter, "{}(", function.declaration.name)?;
|
||||
function.declaration.display_name(formatter)?;
|
||||
write!(formatter, "(")?;
|
||||
|
||||
let mut separator = "";
|
||||
|
||||
@ -290,10 +203,7 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'b, C> std::fmt::Display for TermDisplay<'a, 'b, C>
|
||||
where
|
||||
C: crate::traits::VariableDeclarationDomain
|
||||
+ crate::traits::VariableDeclarationID
|
||||
impl<'a> std::fmt::Display for TermDisplay<'a>
|
||||
{
|
||||
fn fmt(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result
|
||||
{
|
||||
@ -301,47 +211,26 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) struct FormulaDisplay<'a, 'b, C>
|
||||
pub(crate) struct FormulaDisplay<'a>(&'a crate::Formula);
|
||||
|
||||
pub(crate) fn display_formula<'a>(formula: &'a crate::Formula) -> FormulaDisplay<'a>
|
||||
{
|
||||
formula: &'a foliage::Formula,
|
||||
context: &'b C,
|
||||
FormulaDisplay(formula)
|
||||
}
|
||||
|
||||
pub(crate) fn display_formula<'a, 'b, C>(formula: &'a foliage::Formula, context: &'b C)
|
||||
-> FormulaDisplay<'a, 'b, C>
|
||||
where
|
||||
C: crate::traits::VariableDeclarationDomain
|
||||
+ crate::traits::VariableDeclarationID
|
||||
{
|
||||
FormulaDisplay
|
||||
{
|
||||
formula,
|
||||
context,
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'b, C> std::fmt::Debug for FormulaDisplay<'a, 'b, C>
|
||||
where
|
||||
C: crate::traits::InputConstantDeclarationDomain
|
||||
+ crate::traits::VariableDeclarationDomain
|
||||
+ crate::traits::VariableDeclarationID
|
||||
impl<'a> std::fmt::Debug for FormulaDisplay<'a>
|
||||
{
|
||||
fn fmt(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result
|
||||
{
|
||||
let display_variable_declaration = |variable_declaration|
|
||||
display_variable_declaration(variable_declaration, self.context);
|
||||
let display_term = |term| display_term(term, self.context);
|
||||
let display_formula = |formula| display_formula(formula, self.context);
|
||||
|
||||
let mut display_compare = |left, right, notation, integer_operator_name,
|
||||
auxiliary_predicate_name| -> std::fmt::Result
|
||||
{
|
||||
let mut notation = notation;
|
||||
let mut operation_identifier = integer_operator_name;
|
||||
|
||||
let is_left_term_arithmetic = crate::is_term_arithmetic(left, self.context)
|
||||
let is_left_term_arithmetic = crate::is_term_arithmetic(left)
|
||||
.expect("could not determine whether term is arithmetic");
|
||||
let is_right_term_arithmetic = crate::is_term_arithmetic(right, self.context)
|
||||
let is_right_term_arithmetic = crate::is_term_arithmetic(right)
|
||||
.expect("could not determine whether term is arithmetic");
|
||||
|
||||
match (!is_left_term_arithmetic || !is_right_term_arithmetic, auxiliary_predicate_name)
|
||||
@ -387,47 +276,40 @@ where
|
||||
|
||||
use foliage::*;
|
||||
|
||||
match &self.formula
|
||||
match &self.0
|
||||
{
|
||||
// TODO: handle cases with 0 parameters properly
|
||||
Formula::Exists(exists) =>
|
||||
Formula::Exists(quantified_formula)
|
||||
| Formula::ForAll(quantified_formula) =>
|
||||
{
|
||||
write!(formatter, "?[")?;
|
||||
let operator_symbol = match &self.0
|
||||
{
|
||||
Formula::Exists(_) => "?",
|
||||
Formula::ForAll(_) => "!",
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
write!(formatter, "{}[", operator_symbol)?;
|
||||
|
||||
let mut separator = "";
|
||||
|
||||
for parameter in exists.parameters.iter()
|
||||
for parameter in quantified_formula.parameters.iter()
|
||||
{
|
||||
let parameter_domain = self.context.variable_declaration_domain(parameter)
|
||||
.expect("unspecified variable domain");
|
||||
let domain = match parameter.domain()
|
||||
{
|
||||
Ok(domain) => domain,
|
||||
Err(_) => unreachable!(
|
||||
"all variable domains should have been checked at this point"),
|
||||
};
|
||||
|
||||
write!(formatter, "{}{:?}: {}", separator,
|
||||
display_variable_declaration(parameter), display_domain(parameter_domain))?;
|
||||
write!(formatter, "{}", separator)?;
|
||||
parameter.display_name(formatter)?;
|
||||
write!(formatter, ": {}", display_domain(domain))?;
|
||||
|
||||
separator = ", "
|
||||
}
|
||||
|
||||
write!(formatter, "]: ({:?})", display_formula(&exists.argument))?;
|
||||
},
|
||||
// TODO: handle cases with 0 parameters properly
|
||||
Formula::ForAll(for_all) =>
|
||||
{
|
||||
write!(formatter, "![")?;
|
||||
|
||||
let mut separator = "";
|
||||
|
||||
for parameter in for_all.parameters.iter()
|
||||
{
|
||||
let parameter_domain = self.context.variable_declaration_domain(parameter)
|
||||
.expect("unspecified variable domain");
|
||||
|
||||
write!(formatter, "{}{:?}: {}", separator,
|
||||
display_variable_declaration(parameter), display_domain(parameter_domain))?;
|
||||
|
||||
separator = ", "
|
||||
}
|
||||
|
||||
write!(formatter, "]: ({:?})", display_formula(&for_all.argument))?;
|
||||
write!(formatter, "]: ({:?})", display_formula(&quantified_formula.argument))?;
|
||||
},
|
||||
Formula::Not(argument) => write!(formatter, "~{:?}", display_formula(argument))?,
|
||||
// TODO: handle cases with < 2 arguments properly
|
||||
@ -524,7 +406,7 @@ where
|
||||
Formula::Boolean(false) => write!(formatter, "$false")?,
|
||||
Formula::Predicate(predicate) =>
|
||||
{
|
||||
write!(formatter, "{}", predicate.declaration.name)?;
|
||||
predicate.declaration.display_name(formatter)?;
|
||||
|
||||
if !predicate.arguments.is_empty()
|
||||
{
|
||||
@ -536,9 +418,8 @@ where
|
||||
{
|
||||
write!(formatter, "{}", separator)?;
|
||||
|
||||
let is_argument_arithmetic =
|
||||
crate::is_term_arithmetic(argument, self.context)
|
||||
.expect("could not determine whether term is arithmetic");
|
||||
let is_argument_arithmetic = crate::is_term_arithmetic(argument)
|
||||
.expect("could not determine whether term is arithmetic");
|
||||
|
||||
match is_argument_arithmetic
|
||||
{
|
||||
@ -558,11 +439,7 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'b, C> std::fmt::Display for FormulaDisplay<'a, 'b, C>
|
||||
where
|
||||
C: crate::traits::InputConstantDeclarationDomain
|
||||
+ crate::traits::VariableDeclarationDomain
|
||||
+ crate::traits::VariableDeclarationID
|
||||
impl<'a> std::fmt::Display for FormulaDisplay<'a>
|
||||
{
|
||||
fn fmt(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result
|
||||
{
|
||||
|
311
src/problem.rs
311
src/problem.rs
@ -6,6 +6,8 @@ pub use proof_direction::ProofDirection;
|
||||
pub(crate) use section_kind::SectionKind;
|
||||
pub(crate) use statement::{ProofStatus, Statement, StatementKind};
|
||||
|
||||
use foliage::flavor::{FunctionDeclaration as _, PredicateDeclaration as _};
|
||||
|
||||
#[derive(Copy, Clone, Eq, PartialEq)]
|
||||
pub enum ProofResult
|
||||
{
|
||||
@ -15,36 +17,15 @@ pub enum ProofResult
|
||||
}
|
||||
|
||||
type VariableDeclarationIDs
|
||||
= std::collections::BTreeMap::<std::rc::Rc<foliage::VariableDeclaration>, usize>;
|
||||
|
||||
type InputConstantDeclarationDomains
|
||||
= std::collections::BTreeMap<std::rc::Rc<foliage::FunctionDeclaration>, crate::Domain>;
|
||||
|
||||
type VariableDeclarationDomains
|
||||
= std::collections::BTreeMap<std::rc::Rc<foliage::VariableDeclaration>, crate::Domain>;
|
||||
|
||||
struct FormatContext<'a, 'b>
|
||||
{
|
||||
pub program_variable_declaration_ids: std::cell::RefCell<VariableDeclarationIDs>,
|
||||
pub integer_variable_declaration_ids: std::cell::RefCell<VariableDeclarationIDs>,
|
||||
pub input_constant_declaration_domains: &'a InputConstantDeclarationDomains,
|
||||
pub variable_declaration_domains: &'b VariableDeclarationDomains,
|
||||
}
|
||||
= std::collections::BTreeMap::<std::rc::Rc<crate::VariableDeclaration>, usize>;
|
||||
|
||||
pub struct Problem
|
||||
{
|
||||
function_declarations: std::cell::RefCell<foliage::FunctionDeclarations>,
|
||||
pub predicate_declarations: std::cell::RefCell<foliage::PredicateDeclarations>,
|
||||
function_declarations: std::cell::RefCell<crate::FunctionDeclarations>,
|
||||
pub predicate_declarations: std::cell::RefCell<crate::PredicateDeclarations>,
|
||||
|
||||
statements: std::cell::RefCell<std::collections::BTreeMap<SectionKind, Vec<Statement>>>,
|
||||
|
||||
pub input_constant_declarations: std::cell::RefCell<foliage::FunctionDeclarations>,
|
||||
pub input_constant_declaration_domains: std::cell::RefCell<InputConstantDeclarationDomains>,
|
||||
pub input_predicate_declarations: std::cell::RefCell<foliage::PredicateDeclarations>,
|
||||
pub output_predicate_declarations: std::cell::RefCell<foliage::PredicateDeclarations>,
|
||||
// TODO: clean up as variable declarations are dropped
|
||||
variable_declaration_domains: std::cell::RefCell<VariableDeclarationDomains>,
|
||||
|
||||
shell: std::cell::RefCell<crate::output::Shell>,
|
||||
}
|
||||
|
||||
@ -54,27 +35,16 @@ impl Problem
|
||||
{
|
||||
Self
|
||||
{
|
||||
function_declarations: std::cell::RefCell::new(foliage::FunctionDeclarations::new()),
|
||||
predicate_declarations: std::cell::RefCell::new(foliage::PredicateDeclarations::new()),
|
||||
function_declarations: std::cell::RefCell::new(crate::FunctionDeclarations::new()),
|
||||
predicate_declarations: std::cell::RefCell::new(crate::PredicateDeclarations::new()),
|
||||
|
||||
statements: std::cell::RefCell::new(std::collections::BTreeMap::new()),
|
||||
|
||||
input_constant_declarations:
|
||||
std::cell::RefCell::new(foliage::FunctionDeclarations::new()),
|
||||
input_constant_declaration_domains:
|
||||
std::cell::RefCell::new(InputConstantDeclarationDomains::new()),
|
||||
input_predicate_declarations:
|
||||
std::cell::RefCell::new(foliage::PredicateDeclarations::new()),
|
||||
output_predicate_declarations:
|
||||
std::cell::RefCell::new(foliage::PredicateDeclarations::new()),
|
||||
variable_declaration_domains:
|
||||
std::cell::RefCell::new(VariableDeclarationDomains::new()),
|
||||
|
||||
shell: std::cell::RefCell::new(crate::output::Shell::from_stdout()),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn add_statement(&self, section_kind: SectionKind, statement: Statement)
|
||||
pub(crate) fn add_statement(&self, section_kind: SectionKind, mut statement: Statement)
|
||||
{
|
||||
let mut statements = self.statements.borrow_mut();
|
||||
let section = statements.entry(section_kind).or_insert(vec![]);
|
||||
@ -86,10 +56,8 @@ impl Problem
|
||||
-> Result<(), crate::Error>
|
||||
{
|
||||
let predicate_declarations = self.predicate_declarations.borrow();
|
||||
let input_predicate_declarations = self.input_predicate_declarations.borrow();
|
||||
let output_predicate_declarations = self.output_predicate_declarations.borrow();
|
||||
|
||||
if output_predicate_declarations.is_empty()
|
||||
if predicate_declarations.iter().find(|x| *x.is_output.borrow()).is_none()
|
||||
{
|
||||
return Ok(());
|
||||
}
|
||||
@ -97,12 +65,10 @@ impl Problem
|
||||
// Check that only input and output predicates are used in the specification
|
||||
for predicate_declaration in predicate_declarations.iter()
|
||||
{
|
||||
if input_predicate_declarations.contains(predicate_declaration)
|
||||
|| output_predicate_declarations.contains(predicate_declaration)
|
||||
// TODO: refactor
|
||||
if *predicate_declaration.is_input.borrow()
|
||||
|| *predicate_declaration.is_output.borrow()
|
||||
// Auxiliary predicates may occur anywhere
|
||||
|| predicate_declaration.name.starts_with("p__")
|
||||
&& predicate_declaration.name.ends_with("__")
|
||||
|| predicate_declaration.is_built_in()
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@ -133,19 +99,15 @@ impl Problem
|
||||
pub(crate) fn restrict_to_output_predicates(&mut self) -> Result<(), crate::Error>
|
||||
{
|
||||
let predicate_declarations = self.predicate_declarations.borrow();
|
||||
let input_predicate_declarations = self.input_predicate_declarations.borrow();
|
||||
let output_predicate_declarations = self.output_predicate_declarations.borrow();
|
||||
|
||||
// If no output statements were provided, show all predicates by default
|
||||
if output_predicate_declarations.is_empty()
|
||||
if predicate_declarations.iter().find(|x| *x.is_output.borrow()).is_none()
|
||||
{
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let hidden_predicate_declarations =
|
||||
predicate_declarations.iter().filter(|x| !output_predicate_declarations.contains(*x)
|
||||
&& !input_predicate_declarations.contains(*x)
|
||||
&& !(x.name.starts_with("p__") && x.name.ends_with("__")));
|
||||
let hidden_predicate_declarations = predicate_declarations.iter()
|
||||
.filter(|x| !*x.is_output.borrow() && !*x.is_input.borrow() && !x.is_built_in());
|
||||
|
||||
let mut statements = self.statements.borrow_mut();
|
||||
|
||||
@ -181,7 +143,7 @@ impl Problem
|
||||
for statement in statements.iter_mut()
|
||||
{
|
||||
crate::utils::replace_predicate_in_formula_with_completed_definition(
|
||||
&mut statement.formula, &completed_definition, self)?;
|
||||
&mut statement.formula, &completed_definition)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -357,17 +319,7 @@ impl Problem
|
||||
self.shell.borrow_mut().print(&format!("{}: ", statement.kind),
|
||||
&termcolor::ColorSpec::new())?;
|
||||
|
||||
let format_context = FormatContext
|
||||
{
|
||||
program_variable_declaration_ids:
|
||||
std::cell::RefCell::new(VariableDeclarationIDs::new()),
|
||||
integer_variable_declaration_ids:
|
||||
std::cell::RefCell::new(VariableDeclarationIDs::new()),
|
||||
input_constant_declaration_domains: &self.input_constant_declaration_domains.borrow(),
|
||||
variable_declaration_domains: &self.variable_declaration_domains.borrow(),
|
||||
};
|
||||
|
||||
print!("{}", foliage::format::display_formula(&statement.formula, &format_context));
|
||||
print!("{}", statement.formula);
|
||||
|
||||
Ok(())
|
||||
};
|
||||
@ -405,11 +357,7 @@ impl Problem
|
||||
None => break,
|
||||
}
|
||||
|
||||
let mut tptp_problem_to_prove_next_statement = "".to_string();
|
||||
|
||||
self.write_tptp_problem_to_prove_next_statement(
|
||||
&mut tptp_problem_to_prove_next_statement)
|
||||
.map_err(|error| crate::Error::new_write_tptp_program(error))?;
|
||||
let tptp_problem_to_prove_next_statement = format!("{}", self.display_tptp());
|
||||
|
||||
log::trace!("TPTP program:\n{}", &tptp_problem_to_prove_next_statement);
|
||||
|
||||
@ -463,21 +411,20 @@ impl Problem
|
||||
Ok(ProofResult::Proven)
|
||||
}
|
||||
|
||||
fn write_tptp_problem_to_prove_next_statement(&self, formatter: &mut String) -> std::fmt::Result
|
||||
fn display_tptp(&self) -> ProblemTPTPDisplay
|
||||
{
|
||||
use std::fmt::Write as _;
|
||||
ProblemTPTPDisplay(self)
|
||||
}
|
||||
}
|
||||
|
||||
let format_context = FormatContext
|
||||
{
|
||||
program_variable_declaration_ids:
|
||||
std::cell::RefCell::new(VariableDeclarationIDs::new()),
|
||||
integer_variable_declaration_ids:
|
||||
std::cell::RefCell::new(VariableDeclarationIDs::new()),
|
||||
input_constant_declaration_domains: &self.input_constant_declaration_domains.borrow(),
|
||||
variable_declaration_domains: &self.variable_declaration_domains.borrow(),
|
||||
};
|
||||
struct ProblemTPTPDisplay<'p>(&'p Problem);
|
||||
|
||||
let write_title = |formatter: &mut String, title, section_separator| -> std::fmt::Result
|
||||
impl<'p> std::fmt::Display for ProblemTPTPDisplay<'p>
|
||||
{
|
||||
fn fmt(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result
|
||||
{
|
||||
let write_title = |formatter: &mut dyn std::fmt::Write, title, section_separator|
|
||||
-> std::fmt::Result
|
||||
{
|
||||
write!(formatter, "{}{}", section_separator, "%".repeat(72))?;
|
||||
write!(formatter, "\n% {}", title)?;
|
||||
@ -499,42 +446,40 @@ impl Problem
|
||||
= include_str!("output/tptp/preamble_axioms.tptp").trim_end();
|
||||
writeln!(formatter, "{}", tptp_preamble_anthem_types)?;
|
||||
|
||||
if !self.predicate_declarations.borrow().is_empty()
|
||||
|| !self.function_declarations.borrow().is_empty()
|
||||
if !self.0.predicate_declarations.borrow().is_empty()
|
||||
|| !self.0.function_declarations.borrow().is_empty()
|
||||
{
|
||||
write_title(formatter, "types", section_separator)?;
|
||||
|
||||
if !self.predicate_declarations.borrow().is_empty()
|
||||
if !self.0.predicate_declarations.borrow().is_empty()
|
||||
{
|
||||
writeln!(formatter, "% predicate types")?;
|
||||
}
|
||||
|
||||
for predicate_declaration in self.predicate_declarations.borrow().iter()
|
||||
.filter(|x| !(x.name.starts_with("p__") || x.name.ends_with("__")))
|
||||
for predicate_declaration in self.0.predicate_declarations.borrow().iter()
|
||||
.filter(|x| !x.is_built_in())
|
||||
{
|
||||
writeln!(formatter, "tff(type, type, {}).",
|
||||
crate::output::tptp::display_predicate_declaration(predicate_declaration))?;
|
||||
}
|
||||
|
||||
if !self.function_declarations.borrow().is_empty()
|
||||
if !self.0.function_declarations.borrow().is_empty()
|
||||
{
|
||||
writeln!(formatter, "% function types")?;
|
||||
}
|
||||
|
||||
for function_declaration in self.function_declarations.borrow().iter()
|
||||
.filter(|x| !(x.name.starts_with("f__") || x.name.ends_with("__")))
|
||||
for function_declaration in self.0.function_declarations.borrow().iter()
|
||||
.filter(|x| !x.is_built_in())
|
||||
{
|
||||
writeln!(formatter, "tff(type, type, {}).",
|
||||
crate::output::tptp::display_function_declaration(function_declaration,
|
||||
&format_context))?;
|
||||
crate::output::tptp::display_function_declaration(function_declaration))?;
|
||||
}
|
||||
}
|
||||
|
||||
let function_declarations = self.function_declarations.borrow();
|
||||
let symbolic_constants = function_declarations.iter().filter(
|
||||
|x| !self.input_constant_declaration_domains.borrow().contains_key(*x));
|
||||
let function_declarations = self.0.function_declarations.borrow();
|
||||
let symbolic_constants = function_declarations.iter().filter(|x| !*x.is_input.borrow());
|
||||
|
||||
let mut last_symbolic_constant: Option<std::rc::Rc<foliage::FunctionDeclaration>> = None;
|
||||
let mut last_symbolic_constant: Option<std::rc::Rc<crate::FunctionDeclaration>> = None;
|
||||
|
||||
// TODO: put in axioms section
|
||||
for (i, symbolic_constant) in symbolic_constants.enumerate()
|
||||
@ -545,7 +490,7 @@ impl Problem
|
||||
writeln!(formatter, "% axioms for order of symbolic constants")?;
|
||||
}
|
||||
|
||||
if symbolic_constant.arity > 0
|
||||
if symbolic_constant.arity() > 0
|
||||
{
|
||||
// TODO: refactor
|
||||
unimplemented!("n-ary function declarations aren’t supported");
|
||||
@ -553,14 +498,17 @@ impl Problem
|
||||
|
||||
if let Some(last_symbolic_constant) = last_symbolic_constant
|
||||
{
|
||||
writeln!(formatter, "tff(symbolic_constant_order, axiom, p__less__({}, {})).",
|
||||
last_symbolic_constant.name, symbolic_constant.name)?;
|
||||
write!(formatter, "tff(symbolic_constant_order, axiom, p__less__(")?;
|
||||
last_symbolic_constant.display_name(formatter)?;
|
||||
write!(formatter, ", ")?;
|
||||
symbolic_constant.display_name(formatter)?;
|
||||
writeln!(formatter, ")).")?;
|
||||
}
|
||||
|
||||
last_symbolic_constant = Some(std::rc::Rc::clone(symbolic_constant));
|
||||
}
|
||||
|
||||
for (section_kind, statements) in self.statements.borrow().iter()
|
||||
for (section_kind, statements) in self.0.statements.borrow().iter()
|
||||
{
|
||||
if statements.is_empty()
|
||||
{
|
||||
@ -615,7 +563,7 @@ impl Problem
|
||||
|
||||
// TODO: add proper statement type
|
||||
writeln!(formatter, "tff({}, {}, {}).", name, statement_type,
|
||||
crate::output::tptp::display_formula(&statement.formula, &format_context))?;
|
||||
crate::output::tptp::display_formula(&statement.formula))?;
|
||||
}
|
||||
}
|
||||
|
||||
@ -623,23 +571,19 @@ impl Problem
|
||||
}
|
||||
}
|
||||
|
||||
impl foliage::FindOrCreateFunctionDeclaration for Problem
|
||||
impl foliage::FindOrCreateFunctionDeclaration<crate::FoliageFlavor> for Problem
|
||||
{
|
||||
fn find_or_create_function_declaration(&self, name: &str, arity: usize)
|
||||
-> std::rc::Rc<foliage::FunctionDeclaration>
|
||||
-> std::rc::Rc<crate::FunctionDeclaration>
|
||||
{
|
||||
let mut function_declarations = self.function_declarations.borrow_mut();
|
||||
|
||||
match function_declarations.iter().find(|x| x.name == name && x.arity == arity)
|
||||
match function_declarations.iter().find(|x| x.matches_signature(name, arity))
|
||||
{
|
||||
Some(declaration) => std::rc::Rc::clone(&declaration),
|
||||
None =>
|
||||
{
|
||||
let declaration = foliage::FunctionDeclaration
|
||||
{
|
||||
name: name.to_string(),
|
||||
arity,
|
||||
};
|
||||
let declaration = crate::FunctionDeclaration::new(name.to_string(), arity);
|
||||
let declaration = std::rc::Rc::new(declaration);
|
||||
|
||||
function_declarations.insert(std::rc::Rc::clone(&declaration));
|
||||
@ -652,23 +596,19 @@ impl foliage::FindOrCreateFunctionDeclaration for Problem
|
||||
}
|
||||
}
|
||||
|
||||
impl foliage::FindOrCreatePredicateDeclaration for Problem
|
||||
impl foliage::FindOrCreatePredicateDeclaration<crate::FoliageFlavor> for Problem
|
||||
{
|
||||
fn find_or_create_predicate_declaration(&self, name: &str, arity: usize)
|
||||
-> std::rc::Rc<foliage::PredicateDeclaration>
|
||||
-> std::rc::Rc<crate::PredicateDeclaration>
|
||||
{
|
||||
let mut predicate_declarations = self.predicate_declarations.borrow_mut();
|
||||
|
||||
match predicate_declarations.iter().find(|x| x.name == name && x.arity == arity)
|
||||
match predicate_declarations.iter().find(|x| x.matches_signature(name, arity))
|
||||
{
|
||||
Some(declaration) => std::rc::Rc::clone(&declaration),
|
||||
None =>
|
||||
{
|
||||
let declaration = foliage::PredicateDeclaration
|
||||
{
|
||||
name: name.to_string(),
|
||||
arity,
|
||||
};
|
||||
let declaration = crate::PredicateDeclaration::new(name.to_string(), arity);
|
||||
let declaration = std::rc::Rc::new(declaration);
|
||||
|
||||
predicate_declarations.insert(std::rc::Rc::clone(&declaration));
|
||||
@ -681,143 +621,6 @@ impl foliage::FindOrCreatePredicateDeclaration for Problem
|
||||
}
|
||||
}
|
||||
|
||||
impl crate::traits::AssignVariableDeclarationDomain for Problem
|
||||
{
|
||||
fn assign_variable_declaration_domain(&self,
|
||||
variable_declaration: &std::rc::Rc<foliage::VariableDeclaration>, domain: crate::Domain)
|
||||
{
|
||||
let mut variable_declaration_domains = self.variable_declaration_domains.borrow_mut();
|
||||
|
||||
match variable_declaration_domains.get(variable_declaration)
|
||||
{
|
||||
Some(current_domain) => assert_eq!(*current_domain, domain,
|
||||
"inconsistent variable declaration domain"),
|
||||
None =>
|
||||
{
|
||||
variable_declaration_domains
|
||||
.insert(std::rc::Rc::clone(variable_declaration).into(), domain);
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl crate::traits::VariableDeclarationDomain for Problem
|
||||
{
|
||||
fn variable_declaration_domain(&self,
|
||||
variable_declaration: &std::rc::Rc<foliage::VariableDeclaration>)
|
||||
-> Option<crate::Domain>
|
||||
{
|
||||
self.variable_declaration_domains.borrow().iter().find_map(
|
||||
|(x, domain)|
|
||||
match x == variable_declaration
|
||||
{
|
||||
true => Some(*domain),
|
||||
false => None,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'b> FormatContext<'a, 'b>
|
||||
{
|
||||
fn variable_declaration_id(&self,
|
||||
variable_declaration: &std::rc::Rc<foliage::VariableDeclaration>)
|
||||
-> usize
|
||||
{
|
||||
let mut variable_declaration_ids = match self.variable_declaration_domains
|
||||
.get(variable_declaration)
|
||||
{
|
||||
Some(crate::Domain::Program) => self.program_variable_declaration_ids.borrow_mut(),
|
||||
Some(crate::Domain::Integer) => self.integer_variable_declaration_ids.borrow_mut(),
|
||||
None => unreachable!("all variables should be declared at this point"),
|
||||
};
|
||||
|
||||
match variable_declaration_ids.get(variable_declaration)
|
||||
{
|
||||
Some(id) => *id,
|
||||
None =>
|
||||
{
|
||||
let id = variable_declaration_ids.len();
|
||||
variable_declaration_ids.insert(std::rc::Rc::clone(variable_declaration).into(), id);
|
||||
id
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'b> crate::traits::InputConstantDeclarationDomain for FormatContext<'a, 'b>
|
||||
{
|
||||
fn input_constant_declaration_domain(&self,
|
||||
declaration: &std::rc::Rc<foliage::FunctionDeclaration>) -> crate::Domain
|
||||
{
|
||||
// Assume the program domain if not specified otherwise
|
||||
self.input_constant_declaration_domains.get(declaration).map(|x| *x)
|
||||
.unwrap_or(crate::Domain::Program)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'b> crate::traits::VariableDeclarationDomain for FormatContext<'a, 'b>
|
||||
{
|
||||
fn variable_declaration_domain(&self,
|
||||
variable_declaration: &std::rc::Rc<foliage::VariableDeclaration>)
|
||||
-> Option<crate::Domain>
|
||||
{
|
||||
self.variable_declaration_domains.get(variable_declaration)
|
||||
.map(|x| *x)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'b> crate::traits::VariableDeclarationID for FormatContext<'a, 'b>
|
||||
{
|
||||
fn variable_declaration_id(&self,
|
||||
variable_declaration: &std::rc::Rc<foliage::VariableDeclaration>)
|
||||
-> usize
|
||||
{
|
||||
use crate::traits::VariableDeclarationDomain;
|
||||
|
||||
let mut variable_declaration_ids = match self.variable_declaration_domain(
|
||||
variable_declaration)
|
||||
{
|
||||
Some(crate::Domain::Program) => self.program_variable_declaration_ids.borrow_mut(),
|
||||
Some(crate::Domain::Integer) => self.integer_variable_declaration_ids.borrow_mut(),
|
||||
None => panic!("all variables should be declared at this point"),
|
||||
};
|
||||
|
||||
match variable_declaration_ids.get(variable_declaration)
|
||||
{
|
||||
Some(id) =>
|
||||
{
|
||||
*id
|
||||
}
|
||||
None =>
|
||||
{
|
||||
let id = variable_declaration_ids.len();
|
||||
variable_declaration_ids.insert(std::rc::Rc::clone(variable_declaration).into(), id);
|
||||
id
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'b> foliage::format::Format for FormatContext<'a, 'b>
|
||||
{
|
||||
fn display_variable_declaration(&self, formatter: &mut std::fmt::Formatter,
|
||||
variable_declaration: &std::rc::Rc<foliage::VariableDeclaration>)
|
||||
-> std::fmt::Result
|
||||
{
|
||||
let id = self.variable_declaration_id(variable_declaration);
|
||||
let domain = self.variable_declaration_domains.get(variable_declaration)
|
||||
.expect("unspecified variable domain");
|
||||
|
||||
let prefix = match domain
|
||||
{
|
||||
crate::Domain::Integer => "N",
|
||||
crate::Domain::Program => "X",
|
||||
};
|
||||
|
||||
write!(formatter, "{}{}", prefix, id + 1)
|
||||
}
|
||||
}
|
||||
|
||||
fn run_vampire<I, S>(input: &str, arguments: Option<I>)
|
||||
-> Result<(ProofResult, Option<f32>), crate::Error>
|
||||
where
|
||||
|
@ -5,7 +5,7 @@ pub(crate) enum StatementKind
|
||||
{
|
||||
Axiom,
|
||||
Assumption,
|
||||
CompletedDefinition(std::rc::Rc<foliage::PredicateDeclaration>),
|
||||
CompletedDefinition(std::rc::Rc<crate::PredicateDeclaration>),
|
||||
IntegrityConstraint,
|
||||
Lemma(ProofDirection),
|
||||
Assertion,
|
||||
@ -20,7 +20,7 @@ impl std::fmt::Debug for StatementKind
|
||||
Self::Axiom => write!(formatter, "axiom"),
|
||||
Self::Assumption => write!(formatter, "assumption"),
|
||||
Self::CompletedDefinition(ref predicate_declaration) =>
|
||||
write!(formatter, "completed definition of {}", predicate_declaration),
|
||||
write!(formatter, "completed definition of {}", predicate_declaration.declaration),
|
||||
Self::IntegrityConstraint => write!(formatter, "integrity constraint"),
|
||||
Self::Lemma(_) => write!(formatter, "lemma"),
|
||||
Self::Assertion => write!(formatter, "assertion"),
|
||||
@ -52,13 +52,13 @@ pub(crate) struct Statement
|
||||
{
|
||||
pub kind: StatementKind,
|
||||
pub name: Option<String>,
|
||||
pub formula: foliage::Formula,
|
||||
pub formula: crate::Formula,
|
||||
pub proof_status: ProofStatus,
|
||||
}
|
||||
|
||||
impl Statement
|
||||
{
|
||||
pub fn new(kind: StatementKind, formula: foliage::Formula) -> Self
|
||||
pub fn new(kind: StatementKind, formula: crate::Formula) -> Self
|
||||
{
|
||||
Self
|
||||
{
|
||||
|
@ -18,9 +18,9 @@ impl SimplificationResult
|
||||
}
|
||||
}
|
||||
|
||||
fn remove_unnecessary_exists_parameters(formula: &mut foliage::Formula) -> SimplificationResult
|
||||
fn remove_unnecessary_exists_parameters(formula: &mut crate::Formula) -> SimplificationResult
|
||||
{
|
||||
use foliage::Formula;
|
||||
use crate::Formula;
|
||||
|
||||
match formula
|
||||
{
|
||||
@ -123,10 +123,10 @@ fn remove_unnecessary_exists_parameters(formula: &mut foliage::Formula) -> Simpl
|
||||
}
|
||||
}
|
||||
|
||||
fn simplify_quantified_formulas_without_parameters(formula: &mut foliage::Formula)
|
||||
fn simplify_quantified_formulas_without_parameters(formula: &mut crate::Formula)
|
||||
-> SimplificationResult
|
||||
{
|
||||
use foliage::Formula;
|
||||
use crate::Formula;
|
||||
|
||||
match formula
|
||||
{
|
||||
@ -153,7 +153,7 @@ fn simplify_quantified_formulas_without_parameters(formula: &mut foliage::Formul
|
||||
if quantified_formula.parameters.is_empty()
|
||||
{
|
||||
// TODO: remove workaround
|
||||
let mut argument = foliage::Formula::false_();
|
||||
let mut argument = crate::Formula::false_();
|
||||
std::mem::swap(&mut argument, &mut quantified_formula.argument);
|
||||
|
||||
*formula = argument;
|
||||
@ -171,22 +171,22 @@ fn simplify_quantified_formulas_without_parameters(formula: &mut foliage::Formul
|
||||
}
|
||||
}
|
||||
|
||||
fn simplify_trivial_n_ary_formulas(formula: &mut foliage::Formula) -> SimplificationResult
|
||||
fn simplify_trivial_n_ary_formulas(formula: &mut crate::Formula) -> SimplificationResult
|
||||
{
|
||||
use foliage::Formula;
|
||||
use crate::Formula;
|
||||
|
||||
match formula
|
||||
{
|
||||
Formula::And(arguments)
|
||||
| Formula::IfAndOnlyIf(arguments) if arguments.is_empty() =>
|
||||
{
|
||||
*formula = foliage::Formula::true_();
|
||||
*formula = crate::Formula::true_();
|
||||
|
||||
return SimplificationResult::Simplified;
|
||||
},
|
||||
| Formula::Or(arguments) if arguments.is_empty() =>
|
||||
{
|
||||
*formula = foliage::Formula::false_();
|
||||
*formula = crate::Formula::false_();
|
||||
|
||||
return SimplificationResult::Simplified;
|
||||
},
|
||||
@ -225,7 +225,7 @@ fn simplify_trivial_n_ary_formulas(formula: &mut foliage::Formula) -> Simplifica
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn simplify(formula: &mut foliage::Formula)
|
||||
pub(crate) fn simplify(formula: &mut crate::Formula)
|
||||
{
|
||||
loop
|
||||
{
|
||||
|
@ -1,23 +0,0 @@
|
||||
pub(crate) trait InputConstantDeclarationDomain
|
||||
{
|
||||
fn input_constant_declaration_domain(&self,
|
||||
declaration: &std::rc::Rc<foliage::FunctionDeclaration>) -> crate::Domain;
|
||||
}
|
||||
|
||||
pub(crate) trait AssignVariableDeclarationDomain
|
||||
{
|
||||
fn assign_variable_declaration_domain(&self,
|
||||
variable_declaration: &std::rc::Rc<foliage::VariableDeclaration>, domain: crate::Domain);
|
||||
}
|
||||
|
||||
pub(crate) trait VariableDeclarationDomain
|
||||
{
|
||||
fn variable_declaration_domain(&self,
|
||||
variable_declaration: &std::rc::Rc<foliage::VariableDeclaration>) -> Option<crate::Domain>;
|
||||
}
|
||||
|
||||
pub(crate) trait VariableDeclarationID
|
||||
{
|
||||
fn variable_declaration_id(&self,
|
||||
variable_declaration: &std::rc::Rc<foliage::VariableDeclaration>) -> usize;
|
||||
}
|
@ -1,19 +1,18 @@
|
||||
pub(crate) fn choose_value_in_primitive(term: Box<foliage::Term>,
|
||||
variable_declaration: std::rc::Rc<foliage::VariableDeclaration>)
|
||||
-> foliage::Formula
|
||||
pub(crate) fn choose_value_in_primitive(term: Box<crate::Term>,
|
||||
variable_declaration: std::rc::Rc<crate::VariableDeclaration>)
|
||||
-> crate::Formula
|
||||
{
|
||||
let variable = foliage::Term::variable(variable_declaration);
|
||||
let variable = crate::Term::variable(variable_declaration);
|
||||
|
||||
foliage::Formula::equal(Box::new(variable), term)
|
||||
crate::Formula::equal(Box::new(variable), term)
|
||||
}
|
||||
|
||||
pub(crate) fn choose_value_in_term<C>(term: &clingo::ast::Term,
|
||||
variable_declaration: std::rc::Rc<foliage::VariableDeclaration>, context: &C,
|
||||
variable_declaration_stack: &foliage::VariableDeclarationStackLayer)
|
||||
-> Result<foliage::Formula, crate::Error>
|
||||
variable_declaration: std::rc::Rc<crate::VariableDeclaration>, context: &C,
|
||||
variable_declaration_stack: &crate::VariableDeclarationStackLayer)
|
||||
-> Result<crate::Formula, crate::Error>
|
||||
where
|
||||
C: foliage::FindOrCreateFunctionDeclaration
|
||||
+ crate::traits::AssignVariableDeclarationDomain
|
||||
C: foliage::FindOrCreateFunctionDeclaration<crate::FoliageFlavor>,
|
||||
{
|
||||
match term.term_type()
|
||||
{
|
||||
@ -21,15 +20,15 @@ where
|
||||
.map_err(|error| crate::Error::new_logic("clingo error").with(error))?
|
||||
{
|
||||
clingo::SymbolType::Number => Ok(choose_value_in_primitive(
|
||||
Box::new(foliage::Term::integer(symbol.number()
|
||||
Box::new(crate::Term::integer(symbol.number()
|
||||
.map_err(|error| crate::Error::new_logic("clingo error").with(error))?)),
|
||||
variable_declaration)),
|
||||
clingo::SymbolType::Infimum => Ok(choose_value_in_primitive(
|
||||
Box::new(foliage::Term::infimum()), variable_declaration)),
|
||||
Box::new(crate::Term::infimum()), variable_declaration)),
|
||||
clingo::SymbolType::Supremum => Ok(choose_value_in_primitive(
|
||||
Box::new(foliage::Term::supremum()), variable_declaration)),
|
||||
Box::new(crate::Term::supremum()), variable_declaration)),
|
||||
clingo::SymbolType::String => Ok(choose_value_in_primitive(
|
||||
Box::new(foliage::Term::string(symbol.string()
|
||||
Box::new(crate::Term::string(symbol.string()
|
||||
.map_err(|error| crate::Error::new_logic("clingo error").with(error))?
|
||||
.to_string())),
|
||||
variable_declaration)),
|
||||
@ -51,7 +50,7 @@ where
|
||||
|
||||
let constant_declaration =
|
||||
context.find_or_create_function_declaration(constant_name, 0);
|
||||
let function = foliage::Term::function(constant_declaration, vec![]);
|
||||
let function = crate::Term::function(constant_declaration, vec![]);
|
||||
|
||||
Ok(choose_value_in_primitive(Box::new(function), variable_declaration))
|
||||
}
|
||||
@ -60,14 +59,14 @@ where
|
||||
{
|
||||
let other_variable_declaration = match variable_name
|
||||
{
|
||||
// TODO: check
|
||||
// Every occurrence of anonymous variables is treated as if it introduced a fresh
|
||||
// variable declaration
|
||||
"_" => variable_declaration_stack.free_variable_declarations_do_mut(
|
||||
|free_variable_declarations|
|
||||
{
|
||||
// TODO: check domain type
|
||||
let variable_declaration = std::rc::Rc::new(
|
||||
foliage::VariableDeclaration::new("_".to_owned()));
|
||||
crate::VariableDeclaration::new_generated(crate::Domain::Program));
|
||||
|
||||
free_variable_declarations.push(std::rc::Rc::clone(&variable_declaration));
|
||||
|
||||
@ -75,9 +74,7 @@ where
|
||||
}),
|
||||
_ => variable_declaration_stack.find_or_create(variable_name),
|
||||
};
|
||||
context.assign_variable_declaration_domain(&other_variable_declaration,
|
||||
crate::Domain::Program);
|
||||
let other_variable = foliage::Term::variable(other_variable_declaration);
|
||||
let other_variable = crate::Term::variable(other_variable_declaration);
|
||||
|
||||
Ok(choose_value_in_primitive(Box::new(other_variable), variable_declaration))
|
||||
},
|
||||
@ -92,26 +89,21 @@ where
|
||||
| foliage::BinaryOperator::Multiply
|
||||
=>
|
||||
{
|
||||
let parameters = (0..2).map(|_|
|
||||
{
|
||||
let variable_declaration = std::rc::Rc::new(
|
||||
foliage::VariableDeclaration::new("<anonymous>".to_string()));
|
||||
context.assign_variable_declaration_domain(&variable_declaration,
|
||||
crate::Domain::Integer);
|
||||
variable_declaration
|
||||
})
|
||||
.collect::<foliage::VariableDeclarations>();
|
||||
let parameters = (0..2).map(
|
||||
|_| std::rc::Rc::new(crate::VariableDeclaration::new_generated(
|
||||
crate::Domain::Integer)))
|
||||
.collect::<crate::VariableDeclarations>();
|
||||
let parameters = std::rc::Rc::new(parameters);
|
||||
|
||||
let parameter_1 = ¶meters[0];
|
||||
let parameter_2 = ¶meters[1];
|
||||
|
||||
let translated_binary_operation = foliage::Term::binary_operation(operator,
|
||||
Box::new(foliage::Term::variable(std::rc::Rc::clone(¶meter_1))),
|
||||
Box::new(foliage::Term::variable(std::rc::Rc::clone(¶meter_2))));
|
||||
let translated_binary_operation = crate::Term::binary_operation(operator,
|
||||
Box::new(crate::Term::variable(std::rc::Rc::clone(¶meter_1))),
|
||||
Box::new(crate::Term::variable(std::rc::Rc::clone(¶meter_2))));
|
||||
|
||||
let equals = foliage::Formula::equal(
|
||||
Box::new(foliage::Term::variable(variable_declaration)),
|
||||
let equals = crate::Formula::equal(
|
||||
Box::new(crate::Term::variable(variable_declaration)),
|
||||
Box::new(translated_binary_operation));
|
||||
|
||||
let choose_value_from_left_argument = choose_value_in_term(
|
||||
@ -122,24 +114,19 @@ where
|
||||
binary_operation.right(), std::rc::Rc::clone(¶meter_2), context,
|
||||
variable_declaration_stack)?;
|
||||
|
||||
let and = foliage::Formula::And(vec![equals, choose_value_from_left_argument,
|
||||
let and = crate::Formula::And(vec![equals, choose_value_from_left_argument,
|
||||
choose_value_from_right_argument]);
|
||||
|
||||
Ok(foliage::Formula::exists(parameters, Box::new(and)))
|
||||
Ok(crate::Formula::exists(parameters, Box::new(and)))
|
||||
},
|
||||
foliage::BinaryOperator::Divide
|
||||
| foliage::BinaryOperator::Modulo
|
||||
=>
|
||||
{
|
||||
let parameters = (0..4).map(|_|
|
||||
{
|
||||
let variable_declaration = std::rc::Rc::new(
|
||||
foliage::VariableDeclaration::new("<anonymous>".to_string()));
|
||||
context.assign_variable_declaration_domain(&variable_declaration,
|
||||
crate::Domain::Integer);
|
||||
variable_declaration
|
||||
})
|
||||
.collect::<foliage::VariableDeclarations>();
|
||||
let parameters = (0..4).map(
|
||||
|_| std::rc::Rc::new(crate::VariableDeclaration::new_generated(
|
||||
crate::Domain::Integer)))
|
||||
.collect::<crate::VariableDeclarations>();
|
||||
let parameters = std::rc::Rc::new(parameters);
|
||||
|
||||
let parameter_i = ¶meters[0];
|
||||
@ -147,15 +134,15 @@ where
|
||||
let parameter_q = ¶meters[2];
|
||||
let parameter_r = ¶meters[3];
|
||||
|
||||
let j_times_q = foliage::Term::multiply(
|
||||
Box::new(foliage::Term::variable(std::rc::Rc::clone(parameter_j))),
|
||||
Box::new(foliage::Term::variable(std::rc::Rc::clone(parameter_q))));
|
||||
let j_times_q = crate::Term::multiply(
|
||||
Box::new(crate::Term::variable(std::rc::Rc::clone(parameter_j))),
|
||||
Box::new(crate::Term::variable(std::rc::Rc::clone(parameter_q))));
|
||||
|
||||
let j_times_q_plus_r = foliage::Term::add(Box::new(j_times_q),
|
||||
Box::new(foliage::Term::variable(std::rc::Rc::clone(parameter_r))));
|
||||
let j_times_q_plus_r = crate::Term::add(Box::new(j_times_q),
|
||||
Box::new(crate::Term::variable(std::rc::Rc::clone(parameter_r))));
|
||||
|
||||
let i_equals_j_times_q_plus_r = foliage::Formula::equal(
|
||||
Box::new(foliage::Term::variable(std::rc::Rc::clone(parameter_i))),
|
||||
let i_equals_j_times_q_plus_r = crate::Formula::equal(
|
||||
Box::new(crate::Term::variable(std::rc::Rc::clone(parameter_i))),
|
||||
Box::new(j_times_q_plus_r));
|
||||
|
||||
let choose_i_in_t1 = choose_value_in_term(binary_operation.left(),
|
||||
@ -164,26 +151,26 @@ where
|
||||
let choose_j_in_t2 = choose_value_in_term(binary_operation.right(),
|
||||
std::rc::Rc::clone(parameter_j), context, variable_declaration_stack)?;
|
||||
|
||||
let j_not_equal_to_0 = foliage::Formula::not_equal(
|
||||
Box::new(foliage::Term::variable(std::rc::Rc::clone(parameter_j))),
|
||||
Box::new(foliage::Term::integer(0)));
|
||||
let j_not_equal_to_0 = crate::Formula::not_equal(
|
||||
Box::new(crate::Term::variable(std::rc::Rc::clone(parameter_j))),
|
||||
Box::new(crate::Term::integer(0)));
|
||||
|
||||
let r_greater_or_equal_to_0 = foliage::Formula::greater_or_equal(
|
||||
Box::new(foliage::Term::variable(std::rc::Rc::clone(parameter_r))),
|
||||
Box::new(foliage::Term::integer(0)));
|
||||
let r_greater_or_equal_to_0 = crate::Formula::greater_or_equal(
|
||||
Box::new(crate::Term::variable(std::rc::Rc::clone(parameter_r))),
|
||||
Box::new(crate::Term::integer(0)));
|
||||
|
||||
let r_less_than_q = foliage::Formula::less(
|
||||
Box::new(foliage::Term::variable(std::rc::Rc::clone(parameter_r))),
|
||||
Box::new(foliage::Term::variable(std::rc::Rc::clone(parameter_q))));
|
||||
let r_less_than_q = crate::Formula::less(
|
||||
Box::new(crate::Term::variable(std::rc::Rc::clone(parameter_r))),
|
||||
Box::new(crate::Term::variable(std::rc::Rc::clone(parameter_q))));
|
||||
|
||||
let z_equal_to_q = foliage::Formula::equal(
|
||||
let z_equal_to_q = crate::Formula::equal(
|
||||
Box::new(
|
||||
foliage::Term::variable(std::rc::Rc::clone(&variable_declaration))),
|
||||
Box::new(foliage::Term::variable(std::rc::Rc::clone(parameter_q))));
|
||||
crate::Term::variable(std::rc::Rc::clone(&variable_declaration))),
|
||||
Box::new(crate::Term::variable(std::rc::Rc::clone(parameter_q))));
|
||||
|
||||
let z_equal_to_r = foliage::Formula::equal(
|
||||
Box::new(foliage::Term::variable(variable_declaration)),
|
||||
Box::new(foliage::Term::variable(std::rc::Rc::clone(parameter_r))));
|
||||
let z_equal_to_r = crate::Formula::equal(
|
||||
Box::new(crate::Term::variable(variable_declaration)),
|
||||
Box::new(crate::Term::variable(std::rc::Rc::clone(parameter_r))));
|
||||
|
||||
let last_argument = match operator
|
||||
{
|
||||
@ -192,11 +179,11 @@ where
|
||||
_ => return Err(crate::Error::new_logic("unreachable code")),
|
||||
};
|
||||
|
||||
let and = foliage::Formula::and(vec![i_equals_j_times_q_plus_r, choose_i_in_t1,
|
||||
let and = crate::Formula::and(vec![i_equals_j_times_q_plus_r, choose_i_in_t1,
|
||||
choose_j_in_t2, j_not_equal_to_0, r_greater_or_equal_to_0, r_less_than_q,
|
||||
last_argument]);
|
||||
|
||||
Ok(foliage::Formula::exists(parameters, Box::new(and)))
|
||||
Ok(crate::Formula::exists(parameters, Box::new(and)))
|
||||
},
|
||||
foliage::BinaryOperator::Exponentiate =>
|
||||
Err(crate::Error::new_unsupported_language_feature("exponentiation")),
|
||||
@ -210,41 +197,34 @@ where
|
||||
return Err(crate::Error::new_unsupported_language_feature("absolute value")),
|
||||
clingo::ast::UnaryOperator::Minus =>
|
||||
{
|
||||
let parameter_z_prime = std::rc::Rc::new(foliage::VariableDeclaration::new(
|
||||
"<anonymous>".to_string()));
|
||||
context.assign_variable_declaration_domain(¶meter_z_prime,
|
||||
crate::Domain::Integer);
|
||||
let parameter_z_prime = std::rc::Rc::new(
|
||||
crate::VariableDeclaration::new_generated(crate::Domain::Integer));
|
||||
|
||||
let negative_z_prime = foliage::Term::negative(Box::new(
|
||||
foliage::Term::variable(std::rc::Rc::clone(¶meter_z_prime))));
|
||||
let equals = foliage::Formula::equal(
|
||||
Box::new(foliage::Term::variable(variable_declaration)),
|
||||
let negative_z_prime = crate::Term::negative(Box::new(
|
||||
crate::Term::variable(std::rc::Rc::clone(¶meter_z_prime))));
|
||||
let equals = crate::Formula::equal(
|
||||
Box::new(crate::Term::variable(variable_declaration)),
|
||||
Box::new(negative_z_prime));
|
||||
|
||||
let choose_z_prime_in_t_prime = choose_value_in_term(unary_operation.argument(),
|
||||
std::rc::Rc::clone(¶meter_z_prime), context,
|
||||
variable_declaration_stack)?;
|
||||
|
||||
let and = foliage::Formula::and(vec![equals, choose_z_prime_in_t_prime]);
|
||||
let and = crate::Formula::and(vec![equals, choose_z_prime_in_t_prime]);
|
||||
|
||||
let parameters = std::rc::Rc::new(vec![parameter_z_prime]);
|
||||
|
||||
Ok(foliage::Formula::exists(parameters, Box::new(and)))
|
||||
Ok(crate::Formula::exists(parameters, Box::new(and)))
|
||||
},
|
||||
_ => Err(crate::Error::new_not_yet_implemented("todo")),
|
||||
}
|
||||
},
|
||||
clingo::ast::TermType::Interval(interval) =>
|
||||
{
|
||||
let parameters = (0..3).map(|_|
|
||||
{
|
||||
let variable_declaration = std::rc::Rc::new(
|
||||
foliage::VariableDeclaration::new("<anonymous>".to_string()));
|
||||
context.assign_variable_declaration_domain(&variable_declaration,
|
||||
crate::Domain::Integer);
|
||||
variable_declaration
|
||||
})
|
||||
.collect::<foliage::VariableDeclarations>();
|
||||
let parameters = (0..3).map(
|
||||
|_| std::rc::Rc::new(crate::VariableDeclaration::new_generated(
|
||||
crate::Domain::Integer)))
|
||||
.collect::<crate::VariableDeclarations>();
|
||||
let parameters = std::rc::Rc::new(parameters);
|
||||
|
||||
let parameter_i = ¶meters[0];
|
||||
@ -257,22 +237,22 @@ where
|
||||
let choose_j_in_t_2 = choose_value_in_term(interval.right(),
|
||||
std::rc::Rc::clone(parameter_j), context, variable_declaration_stack)?;
|
||||
|
||||
let i_less_than_or_equal_to_k = foliage::Formula::less_or_equal(
|
||||
Box::new(foliage::Term::variable(std::rc::Rc::clone(parameter_i))),
|
||||
Box::new(foliage::Term::variable(std::rc::Rc::clone(parameter_k))));
|
||||
let i_less_than_or_equal_to_k = crate::Formula::less_or_equal(
|
||||
Box::new(crate::Term::variable(std::rc::Rc::clone(parameter_i))),
|
||||
Box::new(crate::Term::variable(std::rc::Rc::clone(parameter_k))));
|
||||
|
||||
let k_less_than_or_equal_to_j = foliage::Formula::less_or_equal(
|
||||
Box::new(foliage::Term::variable(std::rc::Rc::clone(parameter_k))),
|
||||
Box::new(foliage::Term::variable(std::rc::Rc::clone(parameter_j))));
|
||||
let k_less_than_or_equal_to_j = crate::Formula::less_or_equal(
|
||||
Box::new(crate::Term::variable(std::rc::Rc::clone(parameter_k))),
|
||||
Box::new(crate::Term::variable(std::rc::Rc::clone(parameter_j))));
|
||||
|
||||
let z_equals_k = foliage::Formula::equal(
|
||||
Box::new(foliage::Term::variable(variable_declaration)),
|
||||
Box::new(foliage::Term::variable(std::rc::Rc::clone(parameter_k))));
|
||||
let z_equals_k = crate::Formula::equal(
|
||||
Box::new(crate::Term::variable(variable_declaration)),
|
||||
Box::new(crate::Term::variable(std::rc::Rc::clone(parameter_k))));
|
||||
|
||||
let and = foliage::Formula::and(vec![choose_i_in_t_1, choose_j_in_t_2,
|
||||
let and = crate::Formula::and(vec![choose_i_in_t_1, choose_j_in_t_2,
|
||||
i_less_than_or_equal_to_k, k_less_than_or_equal_to_j, z_equals_k]);
|
||||
|
||||
Ok(foliage::Formula::exists(parameters, Box::new(and)))
|
||||
Ok(crate::Formula::exists(parameters, Box::new(and)))
|
||||
},
|
||||
clingo::ast::TermType::Function(_) =>
|
||||
Err(crate::Error::new_unsupported_language_feature("symbolic functions")),
|
||||
|
@ -3,16 +3,17 @@ mod translate_body;
|
||||
|
||||
use head_type::*;
|
||||
use translate_body::*;
|
||||
use crate::traits::AssignVariableDeclarationDomain as _;
|
||||
|
||||
use foliage::flavor::{PredicateDeclaration as _};
|
||||
|
||||
struct PredicateDefinitions
|
||||
{
|
||||
pub parameters: std::rc::Rc<foliage::VariableDeclarations>,
|
||||
pub definitions: Vec<foliage::OpenFormula>,
|
||||
pub parameters: std::rc::Rc<crate::VariableDeclarations>,
|
||||
pub definitions: Vec<crate::OpenFormula>,
|
||||
}
|
||||
|
||||
type Definitions =
|
||||
std::collections::BTreeMap::<std::rc::Rc<foliage::PredicateDeclaration>, PredicateDefinitions>;
|
||||
std::collections::BTreeMap::<std::rc::Rc<crate::PredicateDeclaration>, PredicateDefinitions>;
|
||||
|
||||
pub(crate) struct Translator<'p>
|
||||
{
|
||||
@ -76,8 +77,7 @@ impl<'p> Translator<'p>
|
||||
|
||||
log::info!("read input program “{}”", program_path.as_ref().display());
|
||||
|
||||
let completed_definition = |predicate_declaration, definitions: &mut Definitions,
|
||||
problem: &crate::Problem|
|
||||
let completed_definition = |predicate_declaration, definitions: &mut Definitions|
|
||||
{
|
||||
match definitions.remove(predicate_declaration)
|
||||
{
|
||||
@ -87,19 +87,19 @@ impl<'p> Translator<'p>
|
||||
let or_arguments = predicate_definitions.definitions.into_iter()
|
||||
.map(|x| crate::existential_closure(x))
|
||||
.collect::<Vec<_>>();
|
||||
let or = foliage::Formula::or(or_arguments);
|
||||
let or = crate::Formula::or(or_arguments);
|
||||
|
||||
let head_arguments = predicate_definitions.parameters.iter()
|
||||
.map(|x| foliage::Term::variable(std::rc::Rc::clone(x)))
|
||||
.map(|x| crate::Term::variable(std::rc::Rc::clone(x)))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let head_predicate = foliage::Formula::predicate(
|
||||
let head_predicate = crate::Formula::predicate(
|
||||
std::rc::Rc::clone(predicate_declaration), head_arguments);
|
||||
|
||||
let completed_definition =
|
||||
foliage::Formula::if_and_only_if(vec![head_predicate, or]);
|
||||
crate::Formula::if_and_only_if(vec![head_predicate, or]);
|
||||
|
||||
let open_formula = foliage::OpenFormula
|
||||
let open_formula = crate::OpenFormula
|
||||
{
|
||||
free_variable_declarations: predicate_definitions.parameters,
|
||||
formula: completed_definition,
|
||||
@ -110,27 +110,21 @@ impl<'p> Translator<'p>
|
||||
// This predicate has no definitions, so universally falsify it
|
||||
None =>
|
||||
{
|
||||
let parameters = std::rc::Rc::new((0..predicate_declaration.arity)
|
||||
.map(|_|
|
||||
{
|
||||
let variable_declaration = std::rc::Rc::new(
|
||||
foliage::VariableDeclaration::new("<anonymous>".to_string()));
|
||||
problem.assign_variable_declaration_domain(&variable_declaration,
|
||||
crate::Domain::Program);
|
||||
variable_declaration
|
||||
})
|
||||
let parameters = std::rc::Rc::new((0..predicate_declaration.arity()).map(
|
||||
|_| std::rc::Rc::new(crate::VariableDeclaration::new_generated(
|
||||
crate::Domain::Program)))
|
||||
.collect::<Vec<_>>());
|
||||
|
||||
let head_arguments = parameters.iter()
|
||||
.map(|x| foliage::Term::variable(std::rc::Rc::clone(x)))
|
||||
.map(|x| crate::Term::variable(std::rc::Rc::clone(x)))
|
||||
.collect();
|
||||
|
||||
let head_predicate = foliage::Formula::predicate(
|
||||
let head_predicate = crate::Formula::predicate(
|
||||
std::rc::Rc::clone(predicate_declaration), head_arguments);
|
||||
|
||||
let not = foliage::Formula::not(Box::new(head_predicate));
|
||||
let not = crate::Formula::not(Box::new(head_predicate));
|
||||
|
||||
let open_formula = foliage::OpenFormula
|
||||
let open_formula = crate::OpenFormula
|
||||
{
|
||||
free_variable_declarations: parameters,
|
||||
formula: not,
|
||||
@ -144,9 +138,7 @@ impl<'p> Translator<'p>
|
||||
for predicate_declaration in self.problem.predicate_declarations.borrow().iter()
|
||||
{
|
||||
// Don’t perform completion for input predicates and built-in predicates
|
||||
if self.problem.input_predicate_declarations.borrow().contains(predicate_declaration)
|
||||
|| predicate_declaration.name.starts_with("p__")
|
||||
&& predicate_declaration.name.ends_with("__")
|
||||
if *predicate_declaration.is_input.borrow() || predicate_declaration.is_built_in()
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@ -154,12 +146,18 @@ impl<'p> Translator<'p>
|
||||
let statement_kind = crate::problem::StatementKind::CompletedDefinition(
|
||||
std::rc::Rc::clone(&predicate_declaration));
|
||||
|
||||
let completed_definition = completed_definition(predicate_declaration,
|
||||
&mut self.definitions, self.problem);
|
||||
let mut completed_definition = completed_definition(predicate_declaration,
|
||||
&mut self.definitions);
|
||||
|
||||
crate::autoname_variables(&mut completed_definition);
|
||||
|
||||
//crate::simplify(&mut completed_definition);
|
||||
|
||||
let statement_name =
|
||||
format!("completed_definition_{}", predicate_declaration.tptp_statement_name());
|
||||
|
||||
let statement = crate::problem::Statement::new(statement_kind, completed_definition)
|
||||
.with_name(format!("completed_definition_{}_{}", predicate_declaration.name,
|
||||
predicate_declaration.arity));
|
||||
.with_name(statement_name);
|
||||
|
||||
self.problem.add_statement(crate::problem::SectionKind::CompletedDefinitions,
|
||||
statement);
|
||||
@ -180,15 +178,10 @@ impl<'p> Translator<'p>
|
||||
{
|
||||
if !self.definitions.contains_key(&head_atom.predicate_declaration)
|
||||
{
|
||||
let parameters = std::rc::Rc::new((0..head_atom.predicate_declaration.arity)
|
||||
.map(|_|
|
||||
{
|
||||
let variable_declaration = std::rc::Rc::new(
|
||||
foliage::VariableDeclaration::new("<anonymous>".to_string()));
|
||||
self.problem.assign_variable_declaration_domain(&variable_declaration,
|
||||
crate::Domain::Program);
|
||||
variable_declaration
|
||||
})
|
||||
let parameters = std::rc::Rc::new((0..head_atom.predicate_declaration.arity())
|
||||
.map(
|
||||
|_| std::rc::Rc::new(crate::VariableDeclaration::new_generated(
|
||||
crate::Domain::Program)))
|
||||
.collect());
|
||||
|
||||
self.definitions.insert(
|
||||
@ -207,9 +200,9 @@ impl<'p> Translator<'p>
|
||||
let parameters = std::rc::Rc::clone(&predicate_definitions.parameters);
|
||||
let free_variable_declarations = std::cell::RefCell::new(vec![]);
|
||||
let free_layer =
|
||||
foliage::VariableDeclarationStackLayer::Free(free_variable_declarations);
|
||||
crate::VariableDeclarationStackLayer::Free(free_variable_declarations);
|
||||
let parameters_layer =
|
||||
foliage::VariableDeclarationStackLayer::bound(&free_layer, parameters);
|
||||
crate::VariableDeclarationStackLayer::bound(&free_layer, parameters);
|
||||
|
||||
let mut definition_arguments =
|
||||
translate_body(rule.body(), self.problem, ¶meters_layer)?;
|
||||
@ -220,10 +213,10 @@ impl<'p> Translator<'p>
|
||||
if let HeadType::ChoiceWithSingleAtom(_) = head_type
|
||||
{
|
||||
let head_arguments = predicate_definitions.parameters.iter()
|
||||
.map(|x| foliage::Term::variable(std::rc::Rc::clone(x)))
|
||||
.map(|x| crate::Term::variable(std::rc::Rc::clone(x)))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let head_predicate = foliage::Formula::predicate(
|
||||
let head_predicate = crate::Formula::predicate(
|
||||
std::rc::Rc::clone(&head_atom.predicate_declaration), head_arguments);
|
||||
|
||||
definition_arguments.push(head_predicate);
|
||||
@ -245,7 +238,7 @@ impl<'p> Translator<'p>
|
||||
// TODO: refactor
|
||||
let free_variable_declarations = match free_layer
|
||||
{
|
||||
foliage::VariableDeclarationStackLayer::Free(free_variable_declarations)
|
||||
crate::VariableDeclarationStackLayer::Free(free_variable_declarations)
|
||||
=> free_variable_declarations.into_inner(),
|
||||
_ => unreachable!(),
|
||||
};
|
||||
@ -253,11 +246,11 @@ impl<'p> Translator<'p>
|
||||
let definition = match definition_arguments.len()
|
||||
{
|
||||
1 => definition_arguments.pop().unwrap(),
|
||||
0 => foliage::Formula::true_(),
|
||||
_ => foliage::Formula::and(definition_arguments),
|
||||
0 => crate::Formula::true_(),
|
||||
_ => crate::Formula::and(definition_arguments),
|
||||
};
|
||||
|
||||
let definition = foliage::OpenFormula
|
||||
let definition = crate::OpenFormula
|
||||
{
|
||||
free_variable_declarations: std::rc::Rc::new(free_variable_declarations),
|
||||
formula: definition,
|
||||
@ -269,26 +262,26 @@ impl<'p> Translator<'p>
|
||||
{
|
||||
let free_variable_declarations = std::cell::RefCell::new(vec![]);
|
||||
let free_layer =
|
||||
foliage::VariableDeclarationStackLayer::Free(free_variable_declarations);
|
||||
crate::VariableDeclarationStackLayer::Free(free_variable_declarations);
|
||||
|
||||
let mut arguments = translate_body(rule.body(), self.problem, &free_layer)?;
|
||||
|
||||
// TODO: refactor
|
||||
let free_variable_declarations = match free_layer
|
||||
{
|
||||
foliage::VariableDeclarationStackLayer::Free(free_variable_declarations)
|
||||
crate::VariableDeclarationStackLayer::Free(free_variable_declarations)
|
||||
=> free_variable_declarations.into_inner(),
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
let formula = match arguments.len()
|
||||
{
|
||||
1 => foliage::Formula::not(Box::new(arguments.pop().unwrap())),
|
||||
0 => foliage::Formula::false_(),
|
||||
_ => foliage::Formula::not(Box::new(foliage::Formula::and(arguments))),
|
||||
1 => crate::Formula::not(Box::new(arguments.pop().unwrap())),
|
||||
0 => crate::Formula::false_(),
|
||||
_ => crate::Formula::not(Box::new(crate::Formula::and(arguments))),
|
||||
};
|
||||
|
||||
let open_formula = foliage::OpenFormula
|
||||
let open_formula = crate::OpenFormula
|
||||
{
|
||||
free_variable_declarations: std::rc::Rc::new(free_variable_declarations),
|
||||
formula,
|
||||
@ -296,6 +289,8 @@ 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());
|
||||
|
@ -1,6 +1,6 @@
|
||||
pub(crate) struct HeadAtom<'a>
|
||||
{
|
||||
pub predicate_declaration: std::rc::Rc<foliage::PredicateDeclaration>,
|
||||
pub predicate_declaration: std::rc::Rc<crate::PredicateDeclaration>,
|
||||
pub arguments: &'a [clingo::ast::Term<'a>],
|
||||
}
|
||||
|
||||
@ -15,7 +15,7 @@ pub(crate) enum HeadType<'a>
|
||||
pub(crate) fn determine_head_type<'a, C>(head_literal: &'a clingo::ast::HeadLiteral, context: &C)
|
||||
-> Result<HeadType<'a>, crate::Error>
|
||||
where
|
||||
C: foliage::FindOrCreatePredicateDeclaration
|
||||
C: foliage::FindOrCreatePredicateDeclaration<crate::FoliageFlavor>
|
||||
{
|
||||
let create_head_atom = |function: &'a clingo::ast::Function| -> Result<_, crate::Error>
|
||||
{
|
||||
|
@ -1,11 +1,10 @@
|
||||
// TODO: rename context
|
||||
pub(crate) fn translate_body_term<C>(body_term: &clingo::ast::Term, sign: clingo::ast::Sign,
|
||||
context: &C, variable_declaration_stack: &foliage::VariableDeclarationStackLayer)
|
||||
-> Result<foliage::Formula, crate::Error>
|
||||
context: &C, variable_declaration_stack: &crate::VariableDeclarationStackLayer)
|
||||
-> Result<crate::Formula, crate::Error>
|
||||
where
|
||||
C: foliage::FindOrCreateFunctionDeclaration
|
||||
+ foliage::FindOrCreatePredicateDeclaration
|
||||
+ crate::traits::AssignVariableDeclarationDomain
|
||||
C: foliage::FindOrCreateFunctionDeclaration<crate::FoliageFlavor>
|
||||
+ foliage::FindOrCreatePredicateDeclaration<crate::FoliageFlavor>,
|
||||
{
|
||||
let function = match body_term.term_type()
|
||||
{
|
||||
@ -18,22 +17,16 @@ where
|
||||
let predicate_declaration = context.find_or_create_predicate_declaration(function_name,
|
||||
function.arguments().len());
|
||||
|
||||
let parameters = function.arguments().iter().map(|_|
|
||||
{
|
||||
let variable_declaration = std::rc::Rc::new(
|
||||
foliage::VariableDeclaration::new("<anonymous>".to_string()));
|
||||
context.assign_variable_declaration_domain(&variable_declaration,
|
||||
crate::Domain::Program);
|
||||
variable_declaration
|
||||
})
|
||||
.collect::<foliage::VariableDeclarations>();
|
||||
let parameters = function.arguments().iter().map(
|
||||
|_| std::rc::Rc::new(crate::VariableDeclaration::new_generated(crate::Domain::Program)))
|
||||
.collect::<crate::VariableDeclarations>();
|
||||
let parameters = std::rc::Rc::new(parameters);
|
||||
|
||||
let predicate_arguments = parameters.iter().map(
|
||||
|parameter| foliage::Term::variable(std::rc::Rc::clone(parameter)))
|
||||
|parameter| crate::Term::variable(std::rc::Rc::clone(parameter)))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let predicate = foliage::Formula::predicate(predicate_declaration, predicate_arguments);
|
||||
let predicate = crate::Formula::predicate(predicate_declaration, predicate_arguments);
|
||||
|
||||
let predicate_literal = match sign
|
||||
{
|
||||
@ -41,7 +34,7 @@ where
|
||||
| clingo::ast::Sign::DoubleNegation
|
||||
=> predicate,
|
||||
clingo::ast::Sign::Negation
|
||||
=> foliage::Formula::not(Box::new(predicate)),
|
||||
=> crate::Formula::not(Box::new(predicate)),
|
||||
};
|
||||
|
||||
if function.arguments().is_empty()
|
||||
@ -60,18 +53,17 @@ where
|
||||
|
||||
arguments.push(predicate_literal);
|
||||
|
||||
let and = foliage::Formula::and(arguments);
|
||||
let and = crate::Formula::and(arguments);
|
||||
|
||||
Ok(foliage::Formula::exists(parameters, Box::new(and)))
|
||||
Ok(crate::Formula::exists(parameters, Box::new(and)))
|
||||
}
|
||||
|
||||
pub(crate) fn translate_body_literal<C>(body_literal: &clingo::ast::BodyLiteral,
|
||||
context: &C, variable_declaration_stack: &foliage::VariableDeclarationStackLayer)
|
||||
-> Result<foliage::Formula, crate::Error>
|
||||
context: &C, variable_declaration_stack: &crate::VariableDeclarationStackLayer)
|
||||
-> Result<crate::Formula, crate::Error>
|
||||
where
|
||||
C: foliage::FindOrCreateFunctionDeclaration
|
||||
+ foliage::FindOrCreatePredicateDeclaration
|
||||
+ crate::traits::AssignVariableDeclarationDomain
|
||||
C: foliage::FindOrCreateFunctionDeclaration<crate::FoliageFlavor>
|
||||
+ foliage::FindOrCreatePredicateDeclaration<crate::FoliageFlavor>,
|
||||
{
|
||||
match body_literal.sign()
|
||||
{
|
||||
@ -97,21 +89,16 @@ where
|
||||
_ => return Err(crate::Error::new_logic("unexpected negated Boolean value")),
|
||||
}
|
||||
|
||||
Ok(foliage::Formula::Boolean(value))
|
||||
Ok(crate::Formula::Boolean(value))
|
||||
},
|
||||
clingo::ast::LiteralType::Symbolic(term) => translate_body_term(term, literal.sign(),
|
||||
context, variable_declaration_stack),
|
||||
clingo::ast::LiteralType::Comparison(comparison) =>
|
||||
{
|
||||
let parameters = (0..2).map(|_|
|
||||
{
|
||||
let variable_declaration = std::rc::Rc::new(
|
||||
foliage::VariableDeclaration::new("<anonymous>".to_string()));
|
||||
context.assign_variable_declaration_domain(&variable_declaration,
|
||||
crate::Domain::Program);
|
||||
variable_declaration
|
||||
})
|
||||
.collect::<foliage::VariableDeclarations>();
|
||||
let parameters = (0..2).map(
|
||||
|_| std::rc::Rc::new(crate::VariableDeclaration::new_generated(
|
||||
crate::Domain::Program)))
|
||||
.collect::<crate::VariableDeclarations>();
|
||||
let parameters = std::rc::Rc::new(parameters);
|
||||
|
||||
let mut parameters_iterator = parameters.iter();
|
||||
@ -123,19 +110,19 @@ where
|
||||
let choose_z2_in_t2 = crate::translate::common::choose_value_in_term(comparison.right(),
|
||||
std::rc::Rc::clone(parameter_z2), context, variable_declaration_stack)?;
|
||||
|
||||
let variable_1 = foliage::Term::variable(std::rc::Rc::clone(parameter_z1));
|
||||
let variable_2 = foliage::Term::variable(std::rc::Rc::clone(parameter_z2));
|
||||
let variable_1 = crate::Term::variable(std::rc::Rc::clone(parameter_z1));
|
||||
let variable_2 = crate::Term::variable(std::rc::Rc::clone(parameter_z2));
|
||||
|
||||
let operator = crate::translate::common::translate_comparison_operator(
|
||||
comparison.comparison_type());
|
||||
|
||||
let compare_z1_and_z2 = foliage::Formula::compare(operator, Box::new(variable_1),
|
||||
let compare_z1_and_z2 = crate::Formula::compare(operator, Box::new(variable_1),
|
||||
Box::new(variable_2));
|
||||
|
||||
let and =
|
||||
foliage::Formula::and(vec![choose_z1_in_t1, choose_z2_in_t2, compare_z1_and_z2]);
|
||||
crate::Formula::and(vec![choose_z1_in_t1, choose_z2_in_t2, compare_z1_and_z2]);
|
||||
|
||||
Ok(foliage::Formula::exists(parameters, Box::new(and)))
|
||||
Ok(crate::Formula::exists(parameters, Box::new(and)))
|
||||
},
|
||||
_ => Err(crate::Error::new_unsupported_language_feature(
|
||||
"body literals other than Booleans, terms, or comparisons")),
|
||||
@ -143,15 +130,14 @@ where
|
||||
}
|
||||
|
||||
pub(crate) fn translate_body<C>(body_literals: &[clingo::ast::BodyLiteral], context: &C,
|
||||
variable_declaration_stack: &foliage::VariableDeclarationStackLayer)
|
||||
-> Result<foliage::Formulas, crate::Error>
|
||||
variable_declaration_stack: &crate::VariableDeclarationStackLayer)
|
||||
-> Result<crate::Formulas, crate::Error>
|
||||
where
|
||||
C: foliage::FindOrCreateFunctionDeclaration
|
||||
+ foliage::FindOrCreatePredicateDeclaration
|
||||
+ crate::traits::AssignVariableDeclarationDomain
|
||||
C: foliage::FindOrCreateFunctionDeclaration<crate::FoliageFlavor>
|
||||
+ foliage::FindOrCreatePredicateDeclaration<crate::FoliageFlavor>,
|
||||
{
|
||||
body_literals.iter()
|
||||
.map(|body_literal| translate_body_literal(body_literal, context,
|
||||
variable_declaration_stack))
|
||||
.collect::<Result<foliage::Formulas, crate::Error>>()
|
||||
.collect::<Result<crate::Formulas, crate::Error>>()
|
||||
}
|
||||
|
@ -1,9 +1,11 @@
|
||||
mod arithmetic_terms;
|
||||
mod autoname_variables;
|
||||
mod closures;
|
||||
mod copy_formula;
|
||||
mod output_predicates;
|
||||
mod variables_in_terms;
|
||||
|
||||
pub(crate) use autoname_variables::*;
|
||||
pub(crate) use arithmetic_terms::*;
|
||||
pub(crate) use closures::*;
|
||||
pub(crate) use copy_formula::*;
|
||||
|
@ -1,16 +1,15 @@
|
||||
pub(crate) fn is_term_arithmetic<C>(term: &foliage::Term, context: &C) -> Result<bool, crate::Error>
|
||||
where
|
||||
C: crate::traits::InputConstantDeclarationDomain
|
||||
+ crate::traits::VariableDeclarationDomain
|
||||
pub(crate) fn is_term_arithmetic(term: &crate::Term) -> Result<bool, crate::Error>
|
||||
{
|
||||
use crate::Term;
|
||||
|
||||
match term
|
||||
{
|
||||
foliage::Term::Boolean(_)
|
||||
| foliage::Term::SpecialInteger(_)
|
||||
| foliage::Term::String(_)
|
||||
Term::Boolean(_)
|
||||
| Term::SpecialInteger(_)
|
||||
| Term::String(_)
|
||||
=> Ok(false),
|
||||
foliage::Term::Integer(_) => Ok(true),
|
||||
foliage::Term::Function(ref function) =>
|
||||
Term::Integer(_) => Ok(true),
|
||||
Term::Function(ref function) =>
|
||||
{
|
||||
if !function.arguments.is_empty()
|
||||
{
|
||||
@ -18,20 +17,17 @@ where
|
||||
crate::Error::new_unsupported_language_feature("functions with arguments"));
|
||||
}
|
||||
|
||||
let domain = context.input_constant_declaration_domain(&function.declaration);
|
||||
|
||||
Ok(domain == crate::Domain::Integer)
|
||||
Ok(*function.declaration.domain.borrow() == crate::Domain::Integer)
|
||||
},
|
||||
foliage::Term::Variable(foliage::Variable{ref declaration}) =>
|
||||
match context.variable_declaration_domain(declaration)
|
||||
Term::Variable(crate::Variable{ref declaration}) =>
|
||||
match declaration.domain()?
|
||||
{
|
||||
Some(crate::Domain::Program) => Ok(false),
|
||||
Some(crate::Domain::Integer) => Ok(true),
|
||||
None => Err(crate::Error::new_logic("unspecified variable declaration domain")),
|
||||
crate::Domain::Program => Ok(false),
|
||||
crate::Domain::Integer => Ok(true),
|
||||
},
|
||||
foliage::Term::BinaryOperation(foliage::BinaryOperation{ref left, ref right, ..})
|
||||
=> Ok(is_term_arithmetic(left, context)? && is_term_arithmetic(right, context)?),
|
||||
foliage::Term::UnaryOperation(foliage::UnaryOperation{ref argument, ..})
|
||||
=> is_term_arithmetic(argument, context),
|
||||
Term::BinaryOperation(crate::BinaryOperation{ref left, ref right, ..})
|
||||
=> Ok(is_term_arithmetic(left)? && is_term_arithmetic(right)?),
|
||||
Term::UnaryOperation(crate::UnaryOperation{ref argument, ..})
|
||||
=> is_term_arithmetic(argument),
|
||||
}
|
||||
}
|
||||
|
223
src/utils/autoname_variables.rs
Normal file
223
src/utils/autoname_variables.rs
Normal file
@ -0,0 +1,223 @@
|
||||
struct IDs
|
||||
{
|
||||
program_variable_id: usize,
|
||||
integer_variable_id: usize,
|
||||
}
|
||||
|
||||
impl IDs
|
||||
{
|
||||
pub fn new() -> Self
|
||||
{
|
||||
Self
|
||||
{
|
||||
program_variable_id: 0,
|
||||
integer_variable_id: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
reset_variable_names_in_formula(formula);
|
||||
set_variable_names_in_formula(formula, &mut IDs::new());
|
||||
}
|
@ -1,19 +1,19 @@
|
||||
pub(crate) fn existential_closure(open_formula: foliage::OpenFormula) -> foliage::Formula
|
||||
pub(crate) fn existential_closure(open_formula: crate::OpenFormula) -> crate::Formula
|
||||
{
|
||||
match open_formula.free_variable_declarations.is_empty()
|
||||
{
|
||||
true => open_formula.formula,
|
||||
false => foliage::Formula::exists(open_formula.free_variable_declarations,
|
||||
false => crate::Formula::exists(open_formula.free_variable_declarations,
|
||||
Box::new(open_formula.formula)),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn universal_closure(open_formula: foliage::OpenFormula) -> foliage::Formula
|
||||
pub(crate) fn universal_closure(open_formula: crate::OpenFormula) -> crate::Formula
|
||||
{
|
||||
match open_formula.free_variable_declarations.is_empty()
|
||||
{
|
||||
true => open_formula.formula,
|
||||
false => foliage::Formula::for_all(open_formula.free_variable_declarations,
|
||||
false => crate::Formula::for_all(open_formula.free_variable_declarations,
|
||||
Box::new(open_formula.formula)),
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,10 @@
|
||||
fn replace_variables_in_term(term: &mut foliage::Term,
|
||||
old_variable_declarations: &foliage::VariableDeclarations,
|
||||
new_variable_declarations: &foliage::VariableDeclarations)
|
||||
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 foliage::Term;
|
||||
use crate::Term;
|
||||
|
||||
match term
|
||||
{
|
||||
@ -45,11 +45,11 @@ fn replace_variables_in_term(term: &mut foliage::Term,
|
||||
}
|
||||
}
|
||||
|
||||
fn replace_variables_in_formula(formula: &mut foliage::Formula,
|
||||
old_variable_declarations: &foliage::VariableDeclarations,
|
||||
new_variable_declarations: &foliage::VariableDeclarations)
|
||||
fn replace_variables_in_formula(formula: &mut crate::Formula,
|
||||
old_variable_declarations: &crate::VariableDeclarations,
|
||||
new_variable_declarations: &crate::VariableDeclarations)
|
||||
{
|
||||
use foliage::Formula;
|
||||
use crate::Formula;
|
||||
|
||||
match formula
|
||||
{
|
||||
@ -92,10 +92,10 @@ fn replace_variables_in_formula(formula: &mut foliage::Formula,
|
||||
}
|
||||
}
|
||||
|
||||
fn replace_variable_in_term_with_term(term: &mut foliage::Term,
|
||||
variable_declaration: &foliage::VariableDeclaration, replacement_term: &foliage::Term)
|
||||
fn replace_variable_in_term_with_term(term: &mut crate::Term,
|
||||
variable_declaration: &crate::VariableDeclaration, replacement_term: &crate::Term)
|
||||
{
|
||||
use foliage::Term;
|
||||
use crate::Term;
|
||||
|
||||
match term
|
||||
{
|
||||
@ -127,10 +127,10 @@ fn replace_variable_in_term_with_term(term: &mut foliage::Term,
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn replace_variable_in_formula_with_term(formula: &mut foliage::Formula,
|
||||
variable_declaration: &foliage::VariableDeclaration, replacement_term: &foliage::Term)
|
||||
pub(crate) fn replace_variable_in_formula_with_term(formula: &mut crate::Formula,
|
||||
variable_declaration: &crate::VariableDeclaration, replacement_term: &crate::Term)
|
||||
{
|
||||
use foliage::Formula;
|
||||
use crate::Formula;
|
||||
|
||||
match formula
|
||||
{
|
||||
@ -172,9 +172,9 @@ pub(crate) fn replace_variable_in_formula_with_term(formula: &mut foliage::Formu
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn copy_term(term: &foliage::Term) -> foliage::Term
|
||||
pub(crate) fn copy_term(term: &crate::Term) -> crate::Term
|
||||
{
|
||||
use foliage::Term;
|
||||
use crate::Term;
|
||||
|
||||
match term
|
||||
{
|
||||
@ -194,67 +194,49 @@ pub(crate) fn copy_term(term: &foliage::Term) -> foliage::Term
|
||||
}
|
||||
}
|
||||
|
||||
fn copy_quantified_formula<D>(quantified_expression: &foliage::QuantifiedFormula, declarations: &D)
|
||||
-> foliage::QuantifiedFormula
|
||||
where
|
||||
D: crate::traits::VariableDeclarationDomain + crate::traits::AssignVariableDeclarationDomain,
|
||||
fn copy_quantified_formula(quantified_expression: &crate::QuantifiedFormula)
|
||||
-> crate::QuantifiedFormula
|
||||
{
|
||||
let copy_parameters =
|
||||
quantified_expression.parameters.iter()
|
||||
.map(
|
||||
|parameter|
|
||||
{
|
||||
let copy_parameter = std::rc::Rc::new(
|
||||
foliage::VariableDeclaration::new(parameter.name.clone()));
|
||||
|
||||
if let Some(domain) = declarations.variable_declaration_domain(parameter)
|
||||
{
|
||||
declarations.assign_variable_declaration_domain(©_parameter, domain);
|
||||
}
|
||||
|
||||
copy_parameter
|
||||
})
|
||||
// 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, declarations);
|
||||
let mut copy_argument = copy_formula(&quantified_expression.argument);
|
||||
|
||||
replace_variables_in_formula(&mut copy_argument, &quantified_expression.parameters,
|
||||
©_parameters);
|
||||
|
||||
foliage::QuantifiedFormula::new(copy_parameters, Box::new(copy_argument))
|
||||
crate::QuantifiedFormula::new(copy_parameters, Box::new(copy_argument))
|
||||
}
|
||||
|
||||
pub(crate) fn copy_formula<D>(formula: &foliage::Formula, declarations: &D) -> foliage::Formula
|
||||
where
|
||||
D: crate::traits::VariableDeclarationDomain + crate::traits::AssignVariableDeclarationDomain,
|
||||
pub(crate) fn copy_formula(formula: &crate::Formula) -> crate::Formula
|
||||
{
|
||||
use foliage::Formula;
|
||||
use crate::Formula;
|
||||
|
||||
match formula
|
||||
{
|
||||
Formula::And(arguments) =>
|
||||
Formula::and(arguments.iter().map(
|
||||
|argument| copy_formula(argument, declarations)).collect()),
|
||||
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, declarations)),
|
||||
Formula::Exists(copy_quantified_formula(quantified_formula)),
|
||||
Formula::ForAll(quantified_formula) =>
|
||||
Formula::ForAll(copy_quantified_formula(quantified_formula, declarations)),
|
||||
Formula::ForAll(copy_quantified_formula(quantified_formula)),
|
||||
Formula::IfAndOnlyIf(arguments) =>
|
||||
Formula::if_and_only_if(
|
||||
arguments.iter().map(|argument| copy_formula(argument, declarations)).collect()),
|
||||
arguments.iter().map(|argument| copy_formula(argument)).collect()),
|
||||
Formula::Implies(implies) =>
|
||||
Formula::implies(implies.direction,
|
||||
Box::new(copy_formula(&implies.antecedent, declarations)),
|
||||
Box::new(copy_formula(&implies.implication, declarations))),
|
||||
Formula::Not(argument) => Formula::not(Box::new(copy_formula(&argument, declarations))),
|
||||
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, declarations)).collect()),
|
||||
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()),
|
||||
|
@ -1,8 +1,8 @@
|
||||
pub(crate) fn formula_contains_predicate(formula: &foliage::Formula,
|
||||
predicate_declaration: &foliage::PredicateDeclaration)
|
||||
pub(crate) fn formula_contains_predicate(formula: &crate::Formula,
|
||||
predicate_declaration: &crate::PredicateDeclaration)
|
||||
-> bool
|
||||
{
|
||||
use foliage::Formula;
|
||||
use crate::Formula;
|
||||
|
||||
match formula
|
||||
{
|
||||
@ -24,13 +24,10 @@ pub(crate) fn formula_contains_predicate(formula: &foliage::Formula,
|
||||
}
|
||||
}
|
||||
|
||||
fn replace_predicate_in_formula<D>(formula: &mut foliage::Formula,
|
||||
predicate_to_replace: &foliage::Predicate, replacement_formula: &foliage::Formula,
|
||||
declarations: &D)
|
||||
where
|
||||
D: crate::traits::VariableDeclarationDomain + crate::traits::AssignVariableDeclarationDomain,
|
||||
fn replace_predicate_in_formula(formula: &mut crate::Formula,
|
||||
predicate_to_replace: &crate::Predicate, replacement_formula: &crate::Formula)
|
||||
{
|
||||
use foliage::{Formula, Term};
|
||||
use crate::{Formula, Term};
|
||||
|
||||
match formula
|
||||
{
|
||||
@ -40,29 +37,27 @@ where
|
||||
for mut argument in arguments
|
||||
{
|
||||
replace_predicate_in_formula(&mut argument, predicate_to_replace,
|
||||
replacement_formula, declarations);
|
||||
replacement_formula);
|
||||
},
|
||||
Formula::Boolean(_)
|
||||
| Formula::Compare(_) => (),
|
||||
Formula::Exists(quantified_expression)
|
||||
| Formula::ForAll(quantified_expression) =>
|
||||
replace_predicate_in_formula(&mut quantified_expression.argument, predicate_to_replace,
|
||||
replacement_formula, declarations),
|
||||
replacement_formula),
|
||||
Formula::Implies(implies) =>
|
||||
{
|
||||
replace_predicate_in_formula(&mut implies.antecedent, predicate_to_replace,
|
||||
replacement_formula, declarations);
|
||||
replacement_formula);
|
||||
replace_predicate_in_formula(&mut implies.implication, predicate_to_replace,
|
||||
replacement_formula, declarations);
|
||||
replacement_formula);
|
||||
},
|
||||
Formula::Not(argument) =>
|
||||
replace_predicate_in_formula(argument, predicate_to_replace, replacement_formula,
|
||||
declarations),
|
||||
replace_predicate_in_formula(argument, predicate_to_replace, replacement_formula),
|
||||
Formula::Predicate(predicate) =>
|
||||
if predicate.declaration == predicate_to_replace.declaration
|
||||
{
|
||||
let mut replacement_formula =
|
||||
crate::utils::copy_formula(replacement_formula, declarations);
|
||||
let mut replacement_formula = crate::utils::copy_formula(replacement_formula);
|
||||
|
||||
for (index, argument) in predicate.arguments.iter().enumerate()
|
||||
{
|
||||
@ -81,49 +76,49 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn replace_predicate_in_formula_with_completed_definition<D>(
|
||||
formula: &mut foliage::Formula, completed_definition: &foliage::Formula, declarations: &D)
|
||||
pub(crate) fn replace_predicate_in_formula_with_completed_definition(
|
||||
formula: &mut crate::Formula, completed_definition: &crate::Formula)
|
||||
-> Result<(), crate::Error>
|
||||
where
|
||||
D: crate::traits::VariableDeclarationDomain + crate::traits::AssignVariableDeclarationDomain,
|
||||
{
|
||||
let false_ = foliage::Formula::false_();
|
||||
use crate::Formula;
|
||||
|
||||
let false_ = crate::Formula::false_();
|
||||
|
||||
// TODO: refactor
|
||||
let (completed_definition_predicate, completed_definition) = match completed_definition
|
||||
{
|
||||
foliage::Formula::ForAll(quantified_expression) => match *quantified_expression.argument
|
||||
Formula::ForAll(quantified_expression) => match *quantified_expression.argument
|
||||
{
|
||||
foliage::Formula::IfAndOnlyIf(ref arguments) =>
|
||||
Formula::IfAndOnlyIf(ref arguments) =>
|
||||
{
|
||||
assert_eq!(arguments.len(), 2, "invalid completed definition");
|
||||
|
||||
match arguments[0]
|
||||
{
|
||||
foliage::Formula::Predicate(ref predicate) => (predicate, &arguments[1]),
|
||||
Formula::Predicate(ref predicate) => (predicate, &arguments[1]),
|
||||
_ => panic!("invalid completed definition"),
|
||||
}
|
||||
},
|
||||
foliage::Formula::Not(ref argument) => match **argument
|
||||
Formula::Not(ref argument) => match **argument
|
||||
{
|
||||
foliage::Formula::Predicate(ref predicate) => (predicate, &false_),
|
||||
Formula::Predicate(ref predicate) => (predicate, &false_),
|
||||
_ => panic!("invalid completed definition"),
|
||||
},
|
||||
_ => panic!("invalid completed definition"),
|
||||
},
|
||||
foliage::Formula::IfAndOnlyIf(ref arguments) =>
|
||||
Formula::IfAndOnlyIf(ref arguments) =>
|
||||
{
|
||||
assert_eq!(arguments.len(), 2, "invalid completed definition");
|
||||
|
||||
match arguments[0]
|
||||
{
|
||||
foliage::Formula::Predicate(ref predicate) => (predicate, &arguments[1]),
|
||||
Formula::Predicate(ref predicate) => (predicate, &arguments[1]),
|
||||
_ => panic!("invalid completed definition"),
|
||||
}
|
||||
},
|
||||
foliage::Formula::Not(ref argument) => match **argument
|
||||
Formula::Not(ref argument) => match **argument
|
||||
{
|
||||
foliage::Formula::Predicate(ref predicate) => (predicate, &false_),
|
||||
Formula::Predicate(ref predicate) => (predicate, &false_),
|
||||
_ => panic!("invalid completed definition"),
|
||||
},
|
||||
_ => panic!("invalid completed definition"),
|
||||
@ -139,8 +134,7 @@ where
|
||||
std::rc::Rc::clone(&completed_definition_predicate.declaration)));
|
||||
}
|
||||
|
||||
replace_predicate_in_formula(formula, completed_definition_predicate, completed_definition,
|
||||
declarations);
|
||||
replace_predicate_in_formula(formula, completed_definition_predicate, completed_definition);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
pub(crate) fn term_contains_variable(term: &foliage::Term,
|
||||
variable_declaration: &foliage::VariableDeclaration)
|
||||
pub(crate) fn term_contains_variable(term: &crate::Term,
|
||||
variable_declaration: &crate::VariableDeclaration)
|
||||
-> bool
|
||||
{
|
||||
use foliage::Term;
|
||||
use crate::Term;
|
||||
|
||||
match term
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user