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:
Patrick Lühne 2020-05-22 02:25:00 +02:00
parent b62c379b97
commit 81ddfd450a
Signed by: patrick
GPG Key ID: 05F3611E97A70ABF
20 changed files with 1005 additions and 926 deletions

361
src/ast.rs Normal file
View 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>;

View File

@ -1,3 +1,5 @@
use foliage::flavor::VariableDeclaration as _;
pub type Source = Box<dyn std::error::Error>; pub type Source = Box<dyn std::error::Error>;
pub enum Kind pub enum Kind
@ -21,10 +23,10 @@ pub enum Kind
UnknownProofDirection(String), UnknownProofDirection(String),
UnknownDomainIdentifier(String), UnknownDomainIdentifier(String),
VariableNameNotAllowed(String), VariableNameNotAllowed(String),
FormulaNotClosed(std::rc::Rc<foliage::VariableDeclarations>), FormulaNotClosed(std::rc::Rc<crate::VariableDeclarations>),
NoCompletedDefinitionFound(std::rc::Rc<foliage::PredicateDeclaration>), NoCompletedDefinitionFound(std::rc::Rc<crate::PredicateDeclaration>),
CannotHidePredicate(std::rc::Rc<foliage::PredicateDeclaration>), CannotHidePredicate(std::rc::Rc<crate::PredicateDeclaration>),
PredicateShouldNotOccurInSpecification(std::rc::Rc<foliage::PredicateDeclaration>), PredicateShouldNotOccurInSpecification(std::rc::Rc<crate::PredicateDeclaration>),
WriteTPTPProgram, WriteTPTPProgram,
RunVampire, RunVampire,
// TODO: rename to something Vampire-specific // TODO: rename to something Vampire-specific
@ -146,28 +148,28 @@ impl Error
Self::new(Kind::VariableNameNotAllowed(variable_name)) 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
{ {
Self::new(Kind::FormulaNotClosed(free_variables)) Self::new(Kind::FormulaNotClosed(free_variables))
} }
pub(crate) fn new_no_completed_definition_found( pub(crate) fn new_no_completed_definition_found(
predicate_declaration: std::rc::Rc<foliage::PredicateDeclaration>) predicate_declaration: std::rc::Rc<crate::PredicateDeclaration>)
-> Self -> Self
{ {
Self::new(Kind::NoCompletedDefinitionFound(predicate_declaration)) Self::new(Kind::NoCompletedDefinitionFound(predicate_declaration))
} }
pub(crate) fn new_cannot_hide_predicate( pub(crate) fn new_cannot_hide_predicate(
predicate_declaration: std::rc::Rc<foliage::PredicateDeclaration>) predicate_declaration: std::rc::Rc<crate::PredicateDeclaration>)
-> Self -> Self
{ {
Self::new(Kind::CannotHidePredicate(predicate_declaration)) Self::new(Kind::CannotHidePredicate(predicate_declaration))
} }
pub(crate) fn new_predicate_should_not_occur_in_specification( 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
{ {
Self::new(Kind::PredicateShouldNotOccurInSpecification(predicate_declaration)) 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::WriteTPTPProgram => write!(formatter, "error writing TPTP program"),
Kind::FormulaNotClosed(free_variable_declarations) => Kind::FormulaNotClosed(free_variable_declarations) =>
{ {
let free_variable_names = free_variable_declarations write!(formatter, "formula may not contain free variables (free variables in this formula: ")?;
.iter()
.map(|variable_declaration| &variable_declaration.name);
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: {})", for free_variable_declaration in &**free_variable_declarations
free_variable_names_output) {
write!(formatter, "{}", separator)?;
free_variable_declaration.display_name(formatter)?;
separator = ", ";
}
write!(formatter, ")")
}, },
Kind::NoCompletedDefinitionFound(ref predicate_declaration) => 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) => Kind::CannotHidePredicate(ref predicate_declaration) =>
write!(formatter, write!(formatter,
"cannot hide predicate {} (the completed definition transitively depends on itself)", "cannot hide predicate {} (the completed definition transitively depends on itself)",
predicate_declaration), predicate_declaration.declaration),
Kind::PredicateShouldNotOccurInSpecification(ref predicate_declaration) => Kind::PredicateShouldNotOccurInSpecification(ref predicate_declaration) =>
write!(formatter, write!(formatter,
"{} should not occur in specification because its a private predicate (consider declaring it an input or output predicate)", "{} should not occur in specification because its 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::RunVampire => write!(formatter, "could not run Vampire"),
Kind::ProveProgram(exit_code, ref stdout, ref stderr) => Kind::ProveProgram(exit_code, ref stdout, ref stderr) =>
{ {

View File

@ -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) 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 where
D: foliage::FindOrCreateFunctionDeclaration D: foliage::FindOrCreateFunctionDeclaration<crate::FoliageFlavor>
+ foliage::FindOrCreatePredicateDeclaration + foliage::FindOrCreatePredicateDeclaration<crate::FoliageFlavor>
+ crate::traits::AssignVariableDeclarationDomain,
{ {
let terminator_position = match input.find('.') let terminator_position = match input.find('.')
{ {
@ -106,9 +18,7 @@ where
let open_formula = foliage::parse::formula(formula_input, declarations) let open_formula = foliage::parse::formula(formula_input, declarations)
.map_err(|error| crate::Error::new_parse_formula(error))?; .map_err(|error| crate::Error::new_parse_formula(error))?;
formula_assign_variable_declaration_domains(&open_formula.formula, declarations)?; let open_formula = crate::OpenFormula
let open_formula = foliage::OpenFormula
{ {
free_variable_declarations: open_formula.free_variable_declarations, free_variable_declarations: open_formula.free_variable_declarations,
formula: open_formula.formula, formula: open_formula.formula,
@ -118,11 +28,10 @@ where
} }
fn formula<'i, D>(mut input: &'i str, declarations: &D) 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 where
D: foliage::FindOrCreateFunctionDeclaration D: foliage::FindOrCreateFunctionDeclaration<crate::FoliageFlavor>
+ foliage::FindOrCreatePredicateDeclaration + foliage::FindOrCreatePredicateDeclaration<crate::FoliageFlavor>
+ crate::traits::AssignVariableDeclarationDomain,
{ {
let (open_formula, remaining_input) = open_formula(input, declarations)?; 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) 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); 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; input = remaining_input;
let mut input_predicate_declarations =
problem.input_predicate_declarations.borrow_mut();
use foliage::FindOrCreatePredicateDeclaration as _; use foliage::FindOrCreatePredicateDeclaration as _;
let predicate_declaration = let predicate_declaration =
problem.find_or_create_predicate_declaration(constant_or_predicate_name, arity); 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 // Parse input constant specifiers
else else
@ -279,20 +185,13 @@ fn input_statement_body<'i>(mut input: &'i str, problem: &crate::Problem)
input = remaining_input; input = remaining_input;
let mut input_constant_declarations =
problem.input_constant_declarations.borrow_mut();
use foliage::FindOrCreateFunctionDeclaration as _; use foliage::FindOrCreateFunctionDeclaration as _;
let constant_declaration = let constant_declaration =
problem.find_or_create_function_declaration(constant_or_predicate_name, 0); problem.find_or_create_function_declaration(constant_or_predicate_name, 0);
input_constant_declarations.insert(std::rc::Rc::clone(&constant_declaration)); *constant_declaration.is_input.borrow_mut() = true;
*constant_declaration.domain.borrow_mut() = domain;
let mut input_constant_declaration_domains =
problem.input_constant_declaration_domains.borrow_mut();
input_constant_declaration_domains.insert(constant_declaration, domain);
} }
let mut input_characters = input.chars(); 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; input = remaining_input;
let mut output_predicate_declarations =
problem.output_predicate_declarations.borrow_mut();
use foliage::FindOrCreatePredicateDeclaration as _; use foliage::FindOrCreatePredicateDeclaration as _;
let predicate_declaration = let predicate_declaration =
problem.find_or_create_predicate_declaration(constant_or_predicate_name, arity); 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 else
{ {

View File

@ -1,16 +1,17 @@
#![feature(trait_alias)] #![feature(trait_alias)]
#![feature(vec_remove_item)] #![feature(vec_remove_item)]
mod ast;
pub mod commands; pub mod commands;
pub mod error; pub mod error;
pub mod input; pub mod input;
pub mod output; pub mod output;
pub mod problem; pub mod problem;
pub mod simplify; pub mod simplify;
pub(crate) mod traits;
pub mod translate; pub mod translate;
mod utils; mod utils;
pub use crate::ast::*;
pub use error::Error; pub use error::Error;
pub use problem::Problem; pub use problem::Problem;
pub(crate) use simplify::*; pub(crate) use simplify::*;

View File

@ -1,3 +1,6 @@
use foliage::flavor::{FunctionDeclaration as _, PredicateDeclaration as _,
VariableDeclaration as _};
pub(crate) struct DomainDisplay pub(crate) struct DomainDisplay
{ {
domain: crate::Domain, domain: crate::Domain,
@ -33,37 +36,22 @@ impl std::fmt::Display for DomainDisplay
} }
} }
pub(crate) struct FunctionDeclarationDisplay<'a, 'b, C> pub(crate) struct FunctionDeclarationDisplay<'a>(&'a crate::FunctionDeclaration);
where
C: crate::traits::InputConstantDeclarationDomain pub(crate) fn display_function_declaration<'a>(function_declaration: &'a crate::FunctionDeclaration)
-> FunctionDeclarationDisplay<'a>
{ {
function_declaration: &'a std::rc::Rc<foliage::FunctionDeclaration>, FunctionDeclarationDisplay(function_declaration)
context: &'b C,
} }
pub(crate) fn display_function_declaration<'a, 'b, C>( impl<'a> std::fmt::Debug for FunctionDeclarationDisplay<'a>
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
{ {
fn fmt(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result 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 *self.0.domain.borrow()
let domain_identifier = match domain
{ {
crate::Domain::Integer => "$int", crate::Domain::Integer => "$int",
crate::Domain::Program => "object", crate::Domain::Program => "object",
@ -71,11 +59,11 @@ where
let mut separator = ""; let mut separator = "";
if self.function_declaration.arity > 0 if self.0.arity() > 0
{ {
write!(formatter, " (")?; write!(formatter, " (")?;
for _ in 0..self.function_declaration.arity for _ in 0..self.0.arity()
{ {
write!(formatter, "{}object", separator)?; write!(formatter, "{}object", separator)?;
separator = " * "; separator = " * ";
@ -88,9 +76,7 @@ where
} }
} }
impl<'a, 'b, C> std::fmt::Display for FunctionDeclarationDisplay<'a, 'b, C> impl<'a> std::fmt::Display for FunctionDeclarationDisplay<'a>
where
C: crate::traits::InputConstantDeclarationDomain
{ {
fn fmt(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result 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>( pub(crate) fn display_predicate_declaration<'a>(
predicate_declaration: &'a std::rc::Rc<foliage::PredicateDeclaration>) predicate_declaration: &'a crate::PredicateDeclaration)
-> PredicateDeclarationDisplay<'a> -> PredicateDeclarationDisplay<'a>
{ {
PredicateDeclarationDisplay(predicate_declaration) 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 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 = ""; let mut separator = "";
if self.0.arity > 0 if self.0.arity() > 0
{ {
write!(formatter, " (")?; write!(formatter, " (")?;
for _ in 0..self.0.arity for _ in 0..self.0.arity()
{ {
write!(formatter, "{}object", separator)?; write!(formatter, "{}object", separator)?;
separator = " * "; separator = " * ";
@ -140,94 +127,20 @@ impl<'a> std::fmt::Display for PredicateDeclarationDisplay<'a>
} }
} }
pub(crate) struct VariableDeclarationDisplay<'a, 'b, C> pub(crate) struct TermDisplay<'a>(&'a crate::Term);
where
C: crate::traits::VariableDeclarationDomain pub(crate) fn display_term<'a>(term: &'a crate::Term) -> TermDisplay<'a>
+ crate::traits::VariableDeclarationID
{ {
variable_declaration: &'a std::rc::Rc<foliage::VariableDeclaration>, TermDisplay(term)
context: &'b C,
} }
pub(crate) fn display_variable_declaration<'a, 'b, C>( impl<'a> std::fmt::Debug for TermDisplay<'a>
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
{ {
fn fmt(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result 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::*; use foliage::*;
match &self.term match &self.0
{ {
Term::Boolean(true) => write!(formatter, "$true"), Term::Boolean(true) => write!(formatter, "$true"),
Term::Boolean(false) => write!(formatter, "$false"), Term::Boolean(false) => write!(formatter, "$false"),
@ -239,19 +152,19 @@ where
false => write!(formatter, "{}", value), false => write!(formatter, "{}", value),
}, },
Term::String(_) => panic!("strings not supported in TPTP"), Term::String(_) => panic!("strings not supported in TPTP"),
Term::Variable(variable) => Term::Variable(variable) => variable.declaration.display_name(formatter),
write!(formatter, "{:?}", display_variable_declaration(&variable.declaration)),
Term::Function(function) => 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 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 if function.arguments.len() > 0
{ {
write!(formatter, "{}(", function.declaration.name)?; function.declaration.display_name(formatter)?;
write!(formatter, "(")?;
let mut separator = ""; let mut separator = "";
@ -290,10 +203,7 @@ where
} }
} }
impl<'a, 'b, C> std::fmt::Display for TermDisplay<'a, 'b, C> impl<'a> std::fmt::Display for TermDisplay<'a>
where
C: crate::traits::VariableDeclarationDomain
+ crate::traits::VariableDeclarationID
{ {
fn fmt(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result 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, FormulaDisplay(formula)
context: &'b C,
} }
pub(crate) fn display_formula<'a, 'b, C>(formula: &'a foliage::Formula, context: &'b C) impl<'a> std::fmt::Debug for FormulaDisplay<'a>
-> 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
{ {
fn fmt(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result 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, let mut display_compare = |left, right, notation, integer_operator_name,
auxiliary_predicate_name| -> std::fmt::Result auxiliary_predicate_name| -> std::fmt::Result
{ {
let mut notation = notation; let mut notation = notation;
let mut operation_identifier = integer_operator_name; 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"); .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"); .expect("could not determine whether term is arithmetic");
match (!is_left_term_arithmetic || !is_right_term_arithmetic, auxiliary_predicate_name) match (!is_left_term_arithmetic || !is_right_term_arithmetic, auxiliary_predicate_name)
@ -387,47 +276,40 @@ where
use foliage::*; use foliage::*;
match &self.formula match &self.0
{ {
// TODO: handle cases with 0 parameters properly // 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 = ""; 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) let domain = match parameter.domain()
.expect("unspecified variable domain"); {
Ok(domain) => domain,
Err(_) => unreachable!(
"all variable domains should have been checked at this point"),
};
write!(formatter, "{}{:?}: {}", separator, write!(formatter, "{}", separator)?;
display_variable_declaration(parameter), display_domain(parameter_domain))?; parameter.display_name(formatter)?;
write!(formatter, ": {}", display_domain(domain))?;
separator = ", " separator = ", "
} }
write!(formatter, "]: ({:?})", display_formula(&exists.argument))?; write!(formatter, "]: ({:?})", display_formula(&quantified_formula.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))?;
}, },
Formula::Not(argument) => write!(formatter, "~{:?}", display_formula(argument))?, Formula::Not(argument) => write!(formatter, "~{:?}", display_formula(argument))?,
// TODO: handle cases with < 2 arguments properly // TODO: handle cases with < 2 arguments properly
@ -524,7 +406,7 @@ where
Formula::Boolean(false) => write!(formatter, "$false")?, Formula::Boolean(false) => write!(formatter, "$false")?,
Formula::Predicate(predicate) => Formula::Predicate(predicate) =>
{ {
write!(formatter, "{}", predicate.declaration.name)?; predicate.declaration.display_name(formatter)?;
if !predicate.arguments.is_empty() if !predicate.arguments.is_empty()
{ {
@ -536,9 +418,8 @@ where
{ {
write!(formatter, "{}", separator)?; write!(formatter, "{}", separator)?;
let is_argument_arithmetic = let is_argument_arithmetic = crate::is_term_arithmetic(argument)
crate::is_term_arithmetic(argument, self.context) .expect("could not determine whether term is arithmetic");
.expect("could not determine whether term is arithmetic");
match is_argument_arithmetic match is_argument_arithmetic
{ {
@ -558,11 +439,7 @@ where
} }
} }
impl<'a, 'b, C> std::fmt::Display for FormulaDisplay<'a, 'b, C> impl<'a> std::fmt::Display for FormulaDisplay<'a>
where
C: crate::traits::InputConstantDeclarationDomain
+ crate::traits::VariableDeclarationDomain
+ crate::traits::VariableDeclarationID
{ {
fn fmt(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result fn fmt(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result
{ {

View File

@ -6,6 +6,8 @@ pub use proof_direction::ProofDirection;
pub(crate) use section_kind::SectionKind; pub(crate) use section_kind::SectionKind;
pub(crate) use statement::{ProofStatus, Statement, StatementKind}; pub(crate) use statement::{ProofStatus, Statement, StatementKind};
use foliage::flavor::{FunctionDeclaration as _, PredicateDeclaration as _};
#[derive(Copy, Clone, Eq, PartialEq)] #[derive(Copy, Clone, Eq, PartialEq)]
pub enum ProofResult pub enum ProofResult
{ {
@ -15,36 +17,15 @@ pub enum ProofResult
} }
type VariableDeclarationIDs type VariableDeclarationIDs
= std::collections::BTreeMap::<std::rc::Rc<foliage::VariableDeclaration>, usize>; = std::collections::BTreeMap::<std::rc::Rc<crate::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,
}
pub struct Problem pub struct Problem
{ {
function_declarations: std::cell::RefCell<foliage::FunctionDeclarations>, function_declarations: std::cell::RefCell<crate::FunctionDeclarations>,
pub predicate_declarations: std::cell::RefCell<foliage::PredicateDeclarations>, pub predicate_declarations: std::cell::RefCell<crate::PredicateDeclarations>,
statements: std::cell::RefCell<std::collections::BTreeMap<SectionKind, Vec<Statement>>>, 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>, shell: std::cell::RefCell<crate::output::Shell>,
} }
@ -54,27 +35,16 @@ impl Problem
{ {
Self Self
{ {
function_declarations: std::cell::RefCell::new(foliage::FunctionDeclarations::new()), function_declarations: std::cell::RefCell::new(crate::FunctionDeclarations::new()),
predicate_declarations: std::cell::RefCell::new(foliage::PredicateDeclarations::new()), predicate_declarations: std::cell::RefCell::new(crate::PredicateDeclarations::new()),
statements: std::cell::RefCell::new(std::collections::BTreeMap::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()), 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 mut statements = self.statements.borrow_mut();
let section = statements.entry(section_kind).or_insert(vec![]); let section = statements.entry(section_kind).or_insert(vec![]);
@ -86,10 +56,8 @@ impl Problem
-> Result<(), crate::Error> -> Result<(), crate::Error>
{ {
let predicate_declarations = self.predicate_declarations.borrow(); 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(()); return Ok(());
} }
@ -97,12 +65,10 @@ impl Problem
// Check that only input and output predicates are used in the specification // Check that only input and output predicates are used in the specification
for predicate_declaration in predicate_declarations.iter() for predicate_declaration in predicate_declarations.iter()
{ {
if input_predicate_declarations.contains(predicate_declaration) if *predicate_declaration.is_input.borrow()
|| output_predicate_declarations.contains(predicate_declaration) || *predicate_declaration.is_output.borrow()
// TODO: refactor
// Auxiliary predicates may occur anywhere // Auxiliary predicates may occur anywhere
|| predicate_declaration.name.starts_with("p__") || predicate_declaration.is_built_in()
&& predicate_declaration.name.ends_with("__")
{ {
continue; continue;
} }
@ -133,19 +99,15 @@ impl Problem
pub(crate) fn restrict_to_output_predicates(&mut self) -> Result<(), crate::Error> pub(crate) fn restrict_to_output_predicates(&mut self) -> Result<(), crate::Error>
{ {
let predicate_declarations = self.predicate_declarations.borrow(); 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 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(()); return Ok(());
} }
let hidden_predicate_declarations = let hidden_predicate_declarations = predicate_declarations.iter()
predicate_declarations.iter().filter(|x| !output_predicate_declarations.contains(*x) .filter(|x| !*x.is_output.borrow() && !*x.is_input.borrow() && !x.is_built_in());
&& !input_predicate_declarations.contains(*x)
&& !(x.name.starts_with("p__") && x.name.ends_with("__")));
let mut statements = self.statements.borrow_mut(); let mut statements = self.statements.borrow_mut();
@ -181,7 +143,7 @@ impl Problem
for statement in statements.iter_mut() for statement in statements.iter_mut()
{ {
crate::utils::replace_predicate_in_formula_with_completed_definition( 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), self.shell.borrow_mut().print(&format!("{}: ", statement.kind),
&termcolor::ColorSpec::new())?; &termcolor::ColorSpec::new())?;
let format_context = FormatContext print!("{}", statement.formula);
{
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));
Ok(()) Ok(())
}; };
@ -405,11 +357,7 @@ impl Problem
None => break, None => break,
} }
let mut tptp_problem_to_prove_next_statement = "".to_string(); let tptp_problem_to_prove_next_statement = format!("{}", self.display_tptp());
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))?;
log::trace!("TPTP program:\n{}", &tptp_problem_to_prove_next_statement); log::trace!("TPTP program:\n{}", &tptp_problem_to_prove_next_statement);
@ -463,21 +411,20 @@ impl Problem
Ok(ProofResult::Proven) 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 struct ProblemTPTPDisplay<'p>(&'p Problem);
{
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(),
};
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, "{}{}", section_separator, "%".repeat(72))?;
write!(formatter, "\n% {}", title)?; write!(formatter, "\n% {}", title)?;
@ -499,42 +446,40 @@ impl Problem
= include_str!("output/tptp/preamble_axioms.tptp").trim_end(); = include_str!("output/tptp/preamble_axioms.tptp").trim_end();
writeln!(formatter, "{}", tptp_preamble_anthem_types)?; writeln!(formatter, "{}", tptp_preamble_anthem_types)?;
if !self.predicate_declarations.borrow().is_empty() if !self.0.predicate_declarations.borrow().is_empty()
|| !self.function_declarations.borrow().is_empty() || !self.0.function_declarations.borrow().is_empty()
{ {
write_title(formatter, "types", section_separator)?; 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")?; writeln!(formatter, "% predicate types")?;
} }
for predicate_declaration in self.predicate_declarations.borrow().iter() for predicate_declaration in self.0.predicate_declarations.borrow().iter()
.filter(|x| !(x.name.starts_with("p__") || x.name.ends_with("__"))) .filter(|x| !x.is_built_in())
{ {
writeln!(formatter, "tff(type, type, {}).", writeln!(formatter, "tff(type, type, {}).",
crate::output::tptp::display_predicate_declaration(predicate_declaration))?; 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")?; writeln!(formatter, "% function types")?;
} }
for function_declaration in self.function_declarations.borrow().iter() for function_declaration in self.0.function_declarations.borrow().iter()
.filter(|x| !(x.name.starts_with("f__") || x.name.ends_with("__"))) .filter(|x| !x.is_built_in())
{ {
writeln!(formatter, "tff(type, type, {}).", writeln!(formatter, "tff(type, type, {}).",
crate::output::tptp::display_function_declaration(function_declaration, crate::output::tptp::display_function_declaration(function_declaration))?;
&format_context))?;
} }
} }
let function_declarations = self.function_declarations.borrow(); let function_declarations = self.0.function_declarations.borrow();
let symbolic_constants = function_declarations.iter().filter( let symbolic_constants = function_declarations.iter().filter(|x| !*x.is_input.borrow());
|x| !self.input_constant_declaration_domains.borrow().contains_key(*x));
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 // TODO: put in axioms section
for (i, symbolic_constant) in symbolic_constants.enumerate() for (i, symbolic_constant) in symbolic_constants.enumerate()
@ -545,7 +490,7 @@ impl Problem
writeln!(formatter, "% axioms for order of symbolic constants")?; writeln!(formatter, "% axioms for order of symbolic constants")?;
} }
if symbolic_constant.arity > 0 if symbolic_constant.arity() > 0
{ {
// TODO: refactor // TODO: refactor
unimplemented!("n-ary function declarations arent supported"); unimplemented!("n-ary function declarations arent supported");
@ -553,14 +498,17 @@ impl Problem
if let Some(last_symbolic_constant) = last_symbolic_constant if let Some(last_symbolic_constant) = last_symbolic_constant
{ {
writeln!(formatter, "tff(symbolic_constant_order, axiom, p__less__({}, {})).", write!(formatter, "tff(symbolic_constant_order, axiom, p__less__(")?;
last_symbolic_constant.name, symbolic_constant.name)?; 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)); 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() if statements.is_empty()
{ {
@ -615,7 +563,7 @@ impl Problem
// TODO: add proper statement type // TODO: add proper statement type
writeln!(formatter, "tff({}, {}, {}).", name, 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) 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(); 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), Some(declaration) => std::rc::Rc::clone(&declaration),
None => None =>
{ {
let declaration = foliage::FunctionDeclaration let declaration = crate::FunctionDeclaration::new(name.to_string(), arity);
{
name: name.to_string(),
arity,
};
let declaration = std::rc::Rc::new(declaration); let declaration = std::rc::Rc::new(declaration);
function_declarations.insert(std::rc::Rc::clone(&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) 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(); 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), Some(declaration) => std::rc::Rc::clone(&declaration),
None => None =>
{ {
let declaration = foliage::PredicateDeclaration let declaration = crate::PredicateDeclaration::new(name.to_string(), arity);
{
name: name.to_string(),
arity,
};
let declaration = std::rc::Rc::new(declaration); let declaration = std::rc::Rc::new(declaration);
predicate_declarations.insert(std::rc::Rc::clone(&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>) fn run_vampire<I, S>(input: &str, arguments: Option<I>)
-> Result<(ProofResult, Option<f32>), crate::Error> -> Result<(ProofResult, Option<f32>), crate::Error>
where where

View File

@ -5,7 +5,7 @@ pub(crate) enum StatementKind
{ {
Axiom, Axiom,
Assumption, Assumption,
CompletedDefinition(std::rc::Rc<foliage::PredicateDeclaration>), CompletedDefinition(std::rc::Rc<crate::PredicateDeclaration>),
IntegrityConstraint, IntegrityConstraint,
Lemma(ProofDirection), Lemma(ProofDirection),
Assertion, Assertion,
@ -20,7 +20,7 @@ impl std::fmt::Debug for StatementKind
Self::Axiom => write!(formatter, "axiom"), Self::Axiom => write!(formatter, "axiom"),
Self::Assumption => write!(formatter, "assumption"), Self::Assumption => write!(formatter, "assumption"),
Self::CompletedDefinition(ref predicate_declaration) => 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::IntegrityConstraint => write!(formatter, "integrity constraint"),
Self::Lemma(_) => write!(formatter, "lemma"), Self::Lemma(_) => write!(formatter, "lemma"),
Self::Assertion => write!(formatter, "assertion"), Self::Assertion => write!(formatter, "assertion"),
@ -52,13 +52,13 @@ pub(crate) struct Statement
{ {
pub kind: StatementKind, pub kind: StatementKind,
pub name: Option<String>, pub name: Option<String>,
pub formula: foliage::Formula, pub formula: crate::Formula,
pub proof_status: ProofStatus, pub proof_status: ProofStatus,
} }
impl Statement impl Statement
{ {
pub fn new(kind: StatementKind, formula: foliage::Formula) -> Self pub fn new(kind: StatementKind, formula: crate::Formula) -> Self
{ {
Self Self
{ {

View File

@ -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 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 -> SimplificationResult
{ {
use foliage::Formula; use crate::Formula;
match formula match formula
{ {
@ -153,7 +153,7 @@ fn simplify_quantified_formulas_without_parameters(formula: &mut foliage::Formul
if quantified_formula.parameters.is_empty() if quantified_formula.parameters.is_empty()
{ {
// TODO: remove workaround // TODO: remove workaround
let mut argument = foliage::Formula::false_(); let mut argument = crate::Formula::false_();
std::mem::swap(&mut argument, &mut quantified_formula.argument); std::mem::swap(&mut argument, &mut quantified_formula.argument);
*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 match formula
{ {
Formula::And(arguments) Formula::And(arguments)
| Formula::IfAndOnlyIf(arguments) if arguments.is_empty() => | Formula::IfAndOnlyIf(arguments) if arguments.is_empty() =>
{ {
*formula = foliage::Formula::true_(); *formula = crate::Formula::true_();
return SimplificationResult::Simplified; return SimplificationResult::Simplified;
}, },
| Formula::Or(arguments) if arguments.is_empty() => | Formula::Or(arguments) if arguments.is_empty() =>
{ {
*formula = foliage::Formula::false_(); *formula = crate::Formula::false_();
return SimplificationResult::Simplified; 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 loop
{ {

View File

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

View File

@ -1,19 +1,18 @@
pub(crate) fn choose_value_in_primitive(term: Box<foliage::Term>, pub(crate) fn choose_value_in_primitive(term: Box<crate::Term>,
variable_declaration: std::rc::Rc<foliage::VariableDeclaration>) variable_declaration: std::rc::Rc<crate::VariableDeclaration>)
-> foliage::Formula -> 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, pub(crate) fn choose_value_in_term<C>(term: &clingo::ast::Term,
variable_declaration: std::rc::Rc<foliage::VariableDeclaration>, context: &C, variable_declaration: std::rc::Rc<crate::VariableDeclaration>, context: &C,
variable_declaration_stack: &foliage::VariableDeclarationStackLayer) variable_declaration_stack: &crate::VariableDeclarationStackLayer)
-> Result<foliage::Formula, crate::Error> -> Result<crate::Formula, crate::Error>
where where
C: foliage::FindOrCreateFunctionDeclaration C: foliage::FindOrCreateFunctionDeclaration<crate::FoliageFlavor>,
+ crate::traits::AssignVariableDeclarationDomain
{ {
match term.term_type() match term.term_type()
{ {
@ -21,15 +20,15 @@ where
.map_err(|error| crate::Error::new_logic("clingo error").with(error))? .map_err(|error| crate::Error::new_logic("clingo error").with(error))?
{ {
clingo::SymbolType::Number => Ok(choose_value_in_primitive( 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))?)), .map_err(|error| crate::Error::new_logic("clingo error").with(error))?)),
variable_declaration)), variable_declaration)),
clingo::SymbolType::Infimum => Ok(choose_value_in_primitive( 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( 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( 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))? .map_err(|error| crate::Error::new_logic("clingo error").with(error))?
.to_string())), .to_string())),
variable_declaration)), variable_declaration)),
@ -51,7 +50,7 @@ where
let constant_declaration = let constant_declaration =
context.find_or_create_function_declaration(constant_name, 0); 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)) Ok(choose_value_in_primitive(Box::new(function), variable_declaration))
} }
@ -60,14 +59,14 @@ where
{ {
let other_variable_declaration = match variable_name let other_variable_declaration = match variable_name
{ {
// TODO: check
// Every occurrence of anonymous variables is treated as if it introduced a fresh // Every occurrence of anonymous variables is treated as if it introduced a fresh
// variable declaration // variable declaration
"_" => variable_declaration_stack.free_variable_declarations_do_mut( "_" => variable_declaration_stack.free_variable_declarations_do_mut(
|free_variable_declarations| |free_variable_declarations|
{ {
// TODO: check domain type
let variable_declaration = std::rc::Rc::new( 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)); free_variable_declarations.push(std::rc::Rc::clone(&variable_declaration));
@ -75,9 +74,7 @@ where
}), }),
_ => variable_declaration_stack.find_or_create(variable_name), _ => variable_declaration_stack.find_or_create(variable_name),
}; };
context.assign_variable_declaration_domain(&other_variable_declaration, let other_variable = crate::Term::variable(other_variable_declaration);
crate::Domain::Program);
let other_variable = foliage::Term::variable(other_variable_declaration);
Ok(choose_value_in_primitive(Box::new(other_variable), variable_declaration)) Ok(choose_value_in_primitive(Box::new(other_variable), variable_declaration))
}, },
@ -92,26 +89,21 @@ where
| foliage::BinaryOperator::Multiply | foliage::BinaryOperator::Multiply
=> =>
{ {
let parameters = (0..2).map(|_| let parameters = (0..2).map(
{ |_| std::rc::Rc::new(crate::VariableDeclaration::new_generated(
let variable_declaration = std::rc::Rc::new( crate::Domain::Integer)))
foliage::VariableDeclaration::new("<anonymous>".to_string())); .collect::<crate::VariableDeclarations>();
context.assign_variable_declaration_domain(&variable_declaration,
crate::Domain::Integer);
variable_declaration
})
.collect::<foliage::VariableDeclarations>();
let parameters = std::rc::Rc::new(parameters); let parameters = std::rc::Rc::new(parameters);
let parameter_1 = &parameters[0]; let parameter_1 = &parameters[0];
let parameter_2 = &parameters[1]; let parameter_2 = &parameters[1];
let translated_binary_operation = foliage::Term::binary_operation(operator, let translated_binary_operation = crate::Term::binary_operation(operator,
Box::new(foliage::Term::variable(std::rc::Rc::clone(&parameter_1))), Box::new(crate::Term::variable(std::rc::Rc::clone(&parameter_1))),
Box::new(foliage::Term::variable(std::rc::Rc::clone(&parameter_2)))); Box::new(crate::Term::variable(std::rc::Rc::clone(&parameter_2))));
let equals = foliage::Formula::equal( let equals = crate::Formula::equal(
Box::new(foliage::Term::variable(variable_declaration)), Box::new(crate::Term::variable(variable_declaration)),
Box::new(translated_binary_operation)); Box::new(translated_binary_operation));
let choose_value_from_left_argument = choose_value_in_term( let choose_value_from_left_argument = choose_value_in_term(
@ -122,24 +114,19 @@ where
binary_operation.right(), std::rc::Rc::clone(&parameter_2), context, binary_operation.right(), std::rc::Rc::clone(&parameter_2), context,
variable_declaration_stack)?; 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]); 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::Divide
| foliage::BinaryOperator::Modulo | foliage::BinaryOperator::Modulo
=> =>
{ {
let parameters = (0..4).map(|_| let parameters = (0..4).map(
{ |_| std::rc::Rc::new(crate::VariableDeclaration::new_generated(
let variable_declaration = std::rc::Rc::new( crate::Domain::Integer)))
foliage::VariableDeclaration::new("<anonymous>".to_string())); .collect::<crate::VariableDeclarations>();
context.assign_variable_declaration_domain(&variable_declaration,
crate::Domain::Integer);
variable_declaration
})
.collect::<foliage::VariableDeclarations>();
let parameters = std::rc::Rc::new(parameters); let parameters = std::rc::Rc::new(parameters);
let parameter_i = &parameters[0]; let parameter_i = &parameters[0];
@ -147,15 +134,15 @@ where
let parameter_q = &parameters[2]; let parameter_q = &parameters[2];
let parameter_r = &parameters[3]; let parameter_r = &parameters[3];
let j_times_q = foliage::Term::multiply( let j_times_q = crate::Term::multiply(
Box::new(foliage::Term::variable(std::rc::Rc::clone(parameter_j))), Box::new(crate::Term::variable(std::rc::Rc::clone(parameter_j))),
Box::new(foliage::Term::variable(std::rc::Rc::clone(parameter_q)))); 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), let j_times_q_plus_r = crate::Term::add(Box::new(j_times_q),
Box::new(foliage::Term::variable(std::rc::Rc::clone(parameter_r)))); Box::new(crate::Term::variable(std::rc::Rc::clone(parameter_r))));
let i_equals_j_times_q_plus_r = foliage::Formula::equal( let i_equals_j_times_q_plus_r = crate::Formula::equal(
Box::new(foliage::Term::variable(std::rc::Rc::clone(parameter_i))), Box::new(crate::Term::variable(std::rc::Rc::clone(parameter_i))),
Box::new(j_times_q_plus_r)); Box::new(j_times_q_plus_r));
let choose_i_in_t1 = choose_value_in_term(binary_operation.left(), 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(), let choose_j_in_t2 = choose_value_in_term(binary_operation.right(),
std::rc::Rc::clone(parameter_j), context, variable_declaration_stack)?; std::rc::Rc::clone(parameter_j), context, variable_declaration_stack)?;
let j_not_equal_to_0 = foliage::Formula::not_equal( let j_not_equal_to_0 = crate::Formula::not_equal(
Box::new(foliage::Term::variable(std::rc::Rc::clone(parameter_j))), Box::new(crate::Term::variable(std::rc::Rc::clone(parameter_j))),
Box::new(foliage::Term::integer(0))); Box::new(crate::Term::integer(0)));
let r_greater_or_equal_to_0 = foliage::Formula::greater_or_equal( let r_greater_or_equal_to_0 = crate::Formula::greater_or_equal(
Box::new(foliage::Term::variable(std::rc::Rc::clone(parameter_r))), Box::new(crate::Term::variable(std::rc::Rc::clone(parameter_r))),
Box::new(foliage::Term::integer(0))); Box::new(crate::Term::integer(0)));
let r_less_than_q = foliage::Formula::less( let r_less_than_q = crate::Formula::less(
Box::new(foliage::Term::variable(std::rc::Rc::clone(parameter_r))), Box::new(crate::Term::variable(std::rc::Rc::clone(parameter_r))),
Box::new(foliage::Term::variable(std::rc::Rc::clone(parameter_q)))); 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( Box::new(
foliage::Term::variable(std::rc::Rc::clone(&variable_declaration))), crate::Term::variable(std::rc::Rc::clone(&variable_declaration))),
Box::new(foliage::Term::variable(std::rc::Rc::clone(parameter_q)))); Box::new(crate::Term::variable(std::rc::Rc::clone(parameter_q))));
let z_equal_to_r = foliage::Formula::equal( let z_equal_to_r = crate::Formula::equal(
Box::new(foliage::Term::variable(variable_declaration)), Box::new(crate::Term::variable(variable_declaration)),
Box::new(foliage::Term::variable(std::rc::Rc::clone(parameter_r)))); Box::new(crate::Term::variable(std::rc::Rc::clone(parameter_r))));
let last_argument = match operator let last_argument = match operator
{ {
@ -192,11 +179,11 @@ where
_ => return Err(crate::Error::new_logic("unreachable code")), _ => 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, choose_j_in_t2, j_not_equal_to_0, r_greater_or_equal_to_0, r_less_than_q,
last_argument]); last_argument]);
Ok(foliage::Formula::exists(parameters, Box::new(and))) Ok(crate::Formula::exists(parameters, Box::new(and)))
}, },
foliage::BinaryOperator::Exponentiate => foliage::BinaryOperator::Exponentiate =>
Err(crate::Error::new_unsupported_language_feature("exponentiation")), Err(crate::Error::new_unsupported_language_feature("exponentiation")),
@ -210,41 +197,34 @@ where
return Err(crate::Error::new_unsupported_language_feature("absolute value")), return Err(crate::Error::new_unsupported_language_feature("absolute value")),
clingo::ast::UnaryOperator::Minus => clingo::ast::UnaryOperator::Minus =>
{ {
let parameter_z_prime = std::rc::Rc::new(foliage::VariableDeclaration::new( let parameter_z_prime = std::rc::Rc::new(
"<anonymous>".to_string())); crate::VariableDeclaration::new_generated(crate::Domain::Integer));
context.assign_variable_declaration_domain(&parameter_z_prime,
crate::Domain::Integer);
let negative_z_prime = foliage::Term::negative(Box::new( let negative_z_prime = crate::Term::negative(Box::new(
foliage::Term::variable(std::rc::Rc::clone(&parameter_z_prime)))); crate::Term::variable(std::rc::Rc::clone(&parameter_z_prime))));
let equals = foliage::Formula::equal( let equals = crate::Formula::equal(
Box::new(foliage::Term::variable(variable_declaration)), Box::new(crate::Term::variable(variable_declaration)),
Box::new(negative_z_prime)); Box::new(negative_z_prime));
let choose_z_prime_in_t_prime = choose_value_in_term(unary_operation.argument(), let choose_z_prime_in_t_prime = choose_value_in_term(unary_operation.argument(),
std::rc::Rc::clone(&parameter_z_prime), context, std::rc::Rc::clone(&parameter_z_prime), context,
variable_declaration_stack)?; 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]); 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")), _ => Err(crate::Error::new_not_yet_implemented("todo")),
} }
}, },
clingo::ast::TermType::Interval(interval) => clingo::ast::TermType::Interval(interval) =>
{ {
let parameters = (0..3).map(|_| let parameters = (0..3).map(
{ |_| std::rc::Rc::new(crate::VariableDeclaration::new_generated(
let variable_declaration = std::rc::Rc::new( crate::Domain::Integer)))
foliage::VariableDeclaration::new("<anonymous>".to_string())); .collect::<crate::VariableDeclarations>();
context.assign_variable_declaration_domain(&variable_declaration,
crate::Domain::Integer);
variable_declaration
})
.collect::<foliage::VariableDeclarations>();
let parameters = std::rc::Rc::new(parameters); let parameters = std::rc::Rc::new(parameters);
let parameter_i = &parameters[0]; let parameter_i = &parameters[0];
@ -257,22 +237,22 @@ where
let choose_j_in_t_2 = choose_value_in_term(interval.right(), let choose_j_in_t_2 = choose_value_in_term(interval.right(),
std::rc::Rc::clone(parameter_j), context, variable_declaration_stack)?; std::rc::Rc::clone(parameter_j), context, variable_declaration_stack)?;
let i_less_than_or_equal_to_k = foliage::Formula::less_or_equal( let i_less_than_or_equal_to_k = crate::Formula::less_or_equal(
Box::new(foliage::Term::variable(std::rc::Rc::clone(parameter_i))), Box::new(crate::Term::variable(std::rc::Rc::clone(parameter_i))),
Box::new(foliage::Term::variable(std::rc::Rc::clone(parameter_k)))); Box::new(crate::Term::variable(std::rc::Rc::clone(parameter_k))));
let k_less_than_or_equal_to_j = foliage::Formula::less_or_equal( let k_less_than_or_equal_to_j = crate::Formula::less_or_equal(
Box::new(foliage::Term::variable(std::rc::Rc::clone(parameter_k))), Box::new(crate::Term::variable(std::rc::Rc::clone(parameter_k))),
Box::new(foliage::Term::variable(std::rc::Rc::clone(parameter_j)))); Box::new(crate::Term::variable(std::rc::Rc::clone(parameter_j))));
let z_equals_k = foliage::Formula::equal( let z_equals_k = crate::Formula::equal(
Box::new(foliage::Term::variable(variable_declaration)), Box::new(crate::Term::variable(variable_declaration)),
Box::new(foliage::Term::variable(std::rc::Rc::clone(parameter_k)))); 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]); 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(_) => clingo::ast::TermType::Function(_) =>
Err(crate::Error::new_unsupported_language_feature("symbolic functions")), Err(crate::Error::new_unsupported_language_feature("symbolic functions")),

View File

@ -3,16 +3,17 @@ mod translate_body;
use head_type::*; use head_type::*;
use translate_body::*; use translate_body::*;
use crate::traits::AssignVariableDeclarationDomain as _;
use foliage::flavor::{PredicateDeclaration as _};
struct PredicateDefinitions struct PredicateDefinitions
{ {
pub parameters: std::rc::Rc<foliage::VariableDeclarations>, pub parameters: std::rc::Rc<crate::VariableDeclarations>,
pub definitions: Vec<foliage::OpenFormula>, pub definitions: Vec<crate::OpenFormula>,
} }
type Definitions = 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> pub(crate) struct Translator<'p>
{ {
@ -76,8 +77,7 @@ impl<'p> Translator<'p>
log::info!("read input program “{}”", program_path.as_ref().display()); log::info!("read input program “{}”", program_path.as_ref().display());
let completed_definition = |predicate_declaration, definitions: &mut Definitions, let completed_definition = |predicate_declaration, definitions: &mut Definitions|
problem: &crate::Problem|
{ {
match definitions.remove(predicate_declaration) match definitions.remove(predicate_declaration)
{ {
@ -87,19 +87,19 @@ impl<'p> Translator<'p>
let or_arguments = predicate_definitions.definitions.into_iter() let or_arguments = predicate_definitions.definitions.into_iter()
.map(|x| crate::existential_closure(x)) .map(|x| crate::existential_closure(x))
.collect::<Vec<_>>(); .collect::<Vec<_>>();
let or = foliage::Formula::or(or_arguments); let or = crate::Formula::or(or_arguments);
let head_arguments = predicate_definitions.parameters.iter() 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<_>>(); .collect::<Vec<_>>();
let head_predicate = foliage::Formula::predicate( let head_predicate = crate::Formula::predicate(
std::rc::Rc::clone(predicate_declaration), head_arguments); std::rc::Rc::clone(predicate_declaration), head_arguments);
let completed_definition = 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, free_variable_declarations: predicate_definitions.parameters,
formula: completed_definition, formula: completed_definition,
@ -110,27 +110,21 @@ impl<'p> Translator<'p>
// This predicate has no definitions, so universally falsify it // This predicate has no definitions, so universally falsify it
None => None =>
{ {
let parameters = std::rc::Rc::new((0..predicate_declaration.arity) let parameters = std::rc::Rc::new((0..predicate_declaration.arity()).map(
.map(|_| |_| std::rc::Rc::new(crate::VariableDeclaration::new_generated(
{ crate::Domain::Program)))
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
})
.collect::<Vec<_>>()); .collect::<Vec<_>>());
let head_arguments = parameters.iter() 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(); .collect();
let head_predicate = foliage::Formula::predicate( let head_predicate = crate::Formula::predicate(
std::rc::Rc::clone(predicate_declaration), head_arguments); 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, free_variable_declarations: parameters,
formula: not, formula: not,
@ -144,9 +138,7 @@ impl<'p> Translator<'p>
for predicate_declaration in self.problem.predicate_declarations.borrow().iter() for predicate_declaration in self.problem.predicate_declarations.borrow().iter()
{ {
// Dont perform completion for input predicates and built-in predicates // Dont perform completion for input predicates and built-in predicates
if self.problem.input_predicate_declarations.borrow().contains(predicate_declaration) if *predicate_declaration.is_input.borrow() || predicate_declaration.is_built_in()
|| predicate_declaration.name.starts_with("p__")
&& predicate_declaration.name.ends_with("__")
{ {
continue; continue;
} }
@ -154,12 +146,18 @@ impl<'p> Translator<'p>
let statement_kind = crate::problem::StatementKind::CompletedDefinition( let statement_kind = crate::problem::StatementKind::CompletedDefinition(
std::rc::Rc::clone(&predicate_declaration)); std::rc::Rc::clone(&predicate_declaration));
let completed_definition = completed_definition(predicate_declaration, let mut completed_definition = completed_definition(predicate_declaration,
&mut self.definitions, self.problem); &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) let statement = crate::problem::Statement::new(statement_kind, completed_definition)
.with_name(format!("completed_definition_{}_{}", predicate_declaration.name, .with_name(statement_name);
predicate_declaration.arity));
self.problem.add_statement(crate::problem::SectionKind::CompletedDefinitions, self.problem.add_statement(crate::problem::SectionKind::CompletedDefinitions,
statement); statement);
@ -180,15 +178,10 @@ impl<'p> Translator<'p>
{ {
if !self.definitions.contains_key(&head_atom.predicate_declaration) if !self.definitions.contains_key(&head_atom.predicate_declaration)
{ {
let parameters = std::rc::Rc::new((0..head_atom.predicate_declaration.arity) let parameters = std::rc::Rc::new((0..head_atom.predicate_declaration.arity())
.map(|_| .map(
{ |_| std::rc::Rc::new(crate::VariableDeclaration::new_generated(
let variable_declaration = std::rc::Rc::new( crate::Domain::Program)))
foliage::VariableDeclaration::new("<anonymous>".to_string()));
self.problem.assign_variable_declaration_domain(&variable_declaration,
crate::Domain::Program);
variable_declaration
})
.collect()); .collect());
self.definitions.insert( self.definitions.insert(
@ -207,9 +200,9 @@ impl<'p> Translator<'p>
let parameters = std::rc::Rc::clone(&predicate_definitions.parameters); let parameters = std::rc::Rc::clone(&predicate_definitions.parameters);
let free_variable_declarations = std::cell::RefCell::new(vec![]); let free_variable_declarations = std::cell::RefCell::new(vec![]);
let free_layer = let free_layer =
foliage::VariableDeclarationStackLayer::Free(free_variable_declarations); crate::VariableDeclarationStackLayer::Free(free_variable_declarations);
let parameters_layer = let parameters_layer =
foliage::VariableDeclarationStackLayer::bound(&free_layer, parameters); crate::VariableDeclarationStackLayer::bound(&free_layer, parameters);
let mut definition_arguments = let mut definition_arguments =
translate_body(rule.body(), self.problem, &parameters_layer)?; translate_body(rule.body(), self.problem, &parameters_layer)?;
@ -220,10 +213,10 @@ impl<'p> Translator<'p>
if let HeadType::ChoiceWithSingleAtom(_) = head_type if let HeadType::ChoiceWithSingleAtom(_) = head_type
{ {
let head_arguments = predicate_definitions.parameters.iter() 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<_>>(); .collect::<Vec<_>>();
let head_predicate = foliage::Formula::predicate( let head_predicate = crate::Formula::predicate(
std::rc::Rc::clone(&head_atom.predicate_declaration), head_arguments); std::rc::Rc::clone(&head_atom.predicate_declaration), head_arguments);
definition_arguments.push(head_predicate); definition_arguments.push(head_predicate);
@ -245,7 +238,7 @@ impl<'p> Translator<'p>
// TODO: refactor // TODO: refactor
let free_variable_declarations = match free_layer let free_variable_declarations = match free_layer
{ {
foliage::VariableDeclarationStackLayer::Free(free_variable_declarations) crate::VariableDeclarationStackLayer::Free(free_variable_declarations)
=> free_variable_declarations.into_inner(), => free_variable_declarations.into_inner(),
_ => unreachable!(), _ => unreachable!(),
}; };
@ -253,11 +246,11 @@ impl<'p> Translator<'p>
let definition = match definition_arguments.len() let definition = match definition_arguments.len()
{ {
1 => definition_arguments.pop().unwrap(), 1 => definition_arguments.pop().unwrap(),
0 => foliage::Formula::true_(), 0 => crate::Formula::true_(),
_ => foliage::Formula::and(definition_arguments), _ => crate::Formula::and(definition_arguments),
}; };
let definition = foliage::OpenFormula let definition = crate::OpenFormula
{ {
free_variable_declarations: std::rc::Rc::new(free_variable_declarations), free_variable_declarations: std::rc::Rc::new(free_variable_declarations),
formula: definition, formula: definition,
@ -269,26 +262,26 @@ impl<'p> Translator<'p>
{ {
let free_variable_declarations = std::cell::RefCell::new(vec![]); let free_variable_declarations = std::cell::RefCell::new(vec![]);
let free_layer = 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)?; let mut arguments = translate_body(rule.body(), self.problem, &free_layer)?;
// TODO: refactor // TODO: refactor
let free_variable_declarations = match free_layer let free_variable_declarations = match free_layer
{ {
foliage::VariableDeclarationStackLayer::Free(free_variable_declarations) crate::VariableDeclarationStackLayer::Free(free_variable_declarations)
=> free_variable_declarations.into_inner(), => free_variable_declarations.into_inner(),
_ => unreachable!(), _ => unreachable!(),
}; };
let formula = match arguments.len() let formula = match arguments.len()
{ {
1 => foliage::Formula::not(Box::new(arguments.pop().unwrap())), 1 => crate::Formula::not(Box::new(arguments.pop().unwrap())),
0 => foliage::Formula::false_(), 0 => crate::Formula::false_(),
_ => foliage::Formula::not(Box::new(foliage::Formula::and(arguments))), _ => 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), free_variable_declarations: std::rc::Rc::new(free_variable_declarations),
formula, formula,
@ -296,6 +289,8 @@ impl<'p> Translator<'p>
let integrity_constraint = crate::universal_closure(open_formula); let integrity_constraint = crate::universal_closure(open_formula);
//crate::simplify(&mut integrity_constraint);
let statement = crate::problem::Statement::new( let statement = crate::problem::Statement::new(
crate::problem::StatementKind::IntegrityConstraint, integrity_constraint) crate::problem::StatementKind::IntegrityConstraint, integrity_constraint)
.with_name("integrity_constraint".to_string()); .with_name("integrity_constraint".to_string());

View File

@ -1,6 +1,6 @@
pub(crate) struct HeadAtom<'a> 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>], 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) pub(crate) fn determine_head_type<'a, C>(head_literal: &'a clingo::ast::HeadLiteral, context: &C)
-> Result<HeadType<'a>, crate::Error> -> Result<HeadType<'a>, crate::Error>
where where
C: foliage::FindOrCreatePredicateDeclaration C: foliage::FindOrCreatePredicateDeclaration<crate::FoliageFlavor>
{ {
let create_head_atom = |function: &'a clingo::ast::Function| -> Result<_, crate::Error> let create_head_atom = |function: &'a clingo::ast::Function| -> Result<_, crate::Error>
{ {

View File

@ -1,11 +1,10 @@
// TODO: rename context // TODO: rename context
pub(crate) fn translate_body_term<C>(body_term: &clingo::ast::Term, sign: clingo::ast::Sign, pub(crate) fn translate_body_term<C>(body_term: &clingo::ast::Term, sign: clingo::ast::Sign,
context: &C, variable_declaration_stack: &foliage::VariableDeclarationStackLayer) context: &C, variable_declaration_stack: &crate::VariableDeclarationStackLayer)
-> Result<foliage::Formula, crate::Error> -> Result<crate::Formula, crate::Error>
where where
C: foliage::FindOrCreateFunctionDeclaration C: foliage::FindOrCreateFunctionDeclaration<crate::FoliageFlavor>
+ foliage::FindOrCreatePredicateDeclaration + foliage::FindOrCreatePredicateDeclaration<crate::FoliageFlavor>,
+ crate::traits::AssignVariableDeclarationDomain
{ {
let function = match body_term.term_type() let function = match body_term.term_type()
{ {
@ -18,22 +17,16 @@ where
let predicate_declaration = context.find_or_create_predicate_declaration(function_name, let predicate_declaration = context.find_or_create_predicate_declaration(function_name,
function.arguments().len()); function.arguments().len());
let parameters = function.arguments().iter().map(|_| let parameters = function.arguments().iter().map(
{ |_| std::rc::Rc::new(crate::VariableDeclaration::new_generated(crate::Domain::Program)))
let variable_declaration = std::rc::Rc::new( .collect::<crate::VariableDeclarations>();
foliage::VariableDeclaration::new("<anonymous>".to_string()));
context.assign_variable_declaration_domain(&variable_declaration,
crate::Domain::Program);
variable_declaration
})
.collect::<foliage::VariableDeclarations>();
let parameters = std::rc::Rc::new(parameters); let parameters = std::rc::Rc::new(parameters);
let predicate_arguments = parameters.iter().map( 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<_>>(); .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 let predicate_literal = match sign
{ {
@ -41,7 +34,7 @@ where
| clingo::ast::Sign::DoubleNegation | clingo::ast::Sign::DoubleNegation
=> predicate, => predicate,
clingo::ast::Sign::Negation clingo::ast::Sign::Negation
=> foliage::Formula::not(Box::new(predicate)), => crate::Formula::not(Box::new(predicate)),
}; };
if function.arguments().is_empty() if function.arguments().is_empty()
@ -60,18 +53,17 @@ where
arguments.push(predicate_literal); 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, pub(crate) fn translate_body_literal<C>(body_literal: &clingo::ast::BodyLiteral,
context: &C, variable_declaration_stack: &foliage::VariableDeclarationStackLayer) context: &C, variable_declaration_stack: &crate::VariableDeclarationStackLayer)
-> Result<foliage::Formula, crate::Error> -> Result<crate::Formula, crate::Error>
where where
C: foliage::FindOrCreateFunctionDeclaration C: foliage::FindOrCreateFunctionDeclaration<crate::FoliageFlavor>
+ foliage::FindOrCreatePredicateDeclaration + foliage::FindOrCreatePredicateDeclaration<crate::FoliageFlavor>,
+ crate::traits::AssignVariableDeclarationDomain
{ {
match body_literal.sign() match body_literal.sign()
{ {
@ -97,21 +89,16 @@ where
_ => return Err(crate::Error::new_logic("unexpected negated Boolean value")), _ => 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(), clingo::ast::LiteralType::Symbolic(term) => translate_body_term(term, literal.sign(),
context, variable_declaration_stack), context, variable_declaration_stack),
clingo::ast::LiteralType::Comparison(comparison) => clingo::ast::LiteralType::Comparison(comparison) =>
{ {
let parameters = (0..2).map(|_| let parameters = (0..2).map(
{ |_| std::rc::Rc::new(crate::VariableDeclaration::new_generated(
let variable_declaration = std::rc::Rc::new( crate::Domain::Program)))
foliage::VariableDeclaration::new("<anonymous>".to_string())); .collect::<crate::VariableDeclarations>();
context.assign_variable_declaration_domain(&variable_declaration,
crate::Domain::Program);
variable_declaration
})
.collect::<foliage::VariableDeclarations>();
let parameters = std::rc::Rc::new(parameters); let parameters = std::rc::Rc::new(parameters);
let mut parameters_iterator = parameters.iter(); 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(), let choose_z2_in_t2 = crate::translate::common::choose_value_in_term(comparison.right(),
std::rc::Rc::clone(parameter_z2), context, variable_declaration_stack)?; std::rc::Rc::clone(parameter_z2), context, variable_declaration_stack)?;
let variable_1 = foliage::Term::variable(std::rc::Rc::clone(parameter_z1)); let variable_1 = crate::Term::variable(std::rc::Rc::clone(parameter_z1));
let variable_2 = foliage::Term::variable(std::rc::Rc::clone(parameter_z2)); let variable_2 = crate::Term::variable(std::rc::Rc::clone(parameter_z2));
let operator = crate::translate::common::translate_comparison_operator( let operator = crate::translate::common::translate_comparison_operator(
comparison.comparison_type()); 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)); Box::new(variable_2));
let and = 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( _ => Err(crate::Error::new_unsupported_language_feature(
"body literals other than Booleans, terms, or comparisons")), "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, pub(crate) fn translate_body<C>(body_literals: &[clingo::ast::BodyLiteral], context: &C,
variable_declaration_stack: &foliage::VariableDeclarationStackLayer) variable_declaration_stack: &crate::VariableDeclarationStackLayer)
-> Result<foliage::Formulas, crate::Error> -> Result<crate::Formulas, crate::Error>
where where
C: foliage::FindOrCreateFunctionDeclaration C: foliage::FindOrCreateFunctionDeclaration<crate::FoliageFlavor>
+ foliage::FindOrCreatePredicateDeclaration + foliage::FindOrCreatePredicateDeclaration<crate::FoliageFlavor>,
+ crate::traits::AssignVariableDeclarationDomain
{ {
body_literals.iter() body_literals.iter()
.map(|body_literal| translate_body_literal(body_literal, context, .map(|body_literal| translate_body_literal(body_literal, context,
variable_declaration_stack)) variable_declaration_stack))
.collect::<Result<foliage::Formulas, crate::Error>>() .collect::<Result<crate::Formulas, crate::Error>>()
} }

View File

@ -1,9 +1,11 @@
mod arithmetic_terms; mod arithmetic_terms;
mod autoname_variables;
mod closures; mod closures;
mod copy_formula; mod copy_formula;
mod output_predicates; mod output_predicates;
mod variables_in_terms; mod variables_in_terms;
pub(crate) use autoname_variables::*;
pub(crate) use arithmetic_terms::*; pub(crate) use arithmetic_terms::*;
pub(crate) use closures::*; pub(crate) use closures::*;
pub(crate) use copy_formula::*; pub(crate) use copy_formula::*;

View File

@ -1,16 +1,15 @@
pub(crate) fn is_term_arithmetic<C>(term: &foliage::Term, context: &C) -> Result<bool, crate::Error> pub(crate) fn is_term_arithmetic(term: &crate::Term) -> Result<bool, crate::Error>
where
C: crate::traits::InputConstantDeclarationDomain
+ crate::traits::VariableDeclarationDomain
{ {
use crate::Term;
match term match term
{ {
foliage::Term::Boolean(_) Term::Boolean(_)
| foliage::Term::SpecialInteger(_) | Term::SpecialInteger(_)
| foliage::Term::String(_) | Term::String(_)
=> Ok(false), => Ok(false),
foliage::Term::Integer(_) => Ok(true), Term::Integer(_) => Ok(true),
foliage::Term::Function(ref function) => Term::Function(ref function) =>
{ {
if !function.arguments.is_empty() if !function.arguments.is_empty()
{ {
@ -18,20 +17,17 @@ where
crate::Error::new_unsupported_language_feature("functions with arguments")); crate::Error::new_unsupported_language_feature("functions with arguments"));
} }
let domain = context.input_constant_declaration_domain(&function.declaration); Ok(*function.declaration.domain.borrow() == crate::Domain::Integer)
Ok(domain == crate::Domain::Integer)
}, },
foliage::Term::Variable(foliage::Variable{ref declaration}) => Term::Variable(crate::Variable{ref declaration}) =>
match context.variable_declaration_domain(declaration) match declaration.domain()?
{ {
Some(crate::Domain::Program) => Ok(false), crate::Domain::Program => Ok(false),
Some(crate::Domain::Integer) => Ok(true), crate::Domain::Integer => Ok(true),
None => Err(crate::Error::new_logic("unspecified variable declaration domain")),
}, },
foliage::Term::BinaryOperation(foliage::BinaryOperation{ref left, ref right, ..}) Term::BinaryOperation(crate::BinaryOperation{ref left, ref right, ..})
=> Ok(is_term_arithmetic(left, context)? && is_term_arithmetic(right, context)?), => Ok(is_term_arithmetic(left)? && is_term_arithmetic(right)?),
foliage::Term::UnaryOperation(foliage::UnaryOperation{ref argument, ..}) Term::UnaryOperation(crate::UnaryOperation{ref argument, ..})
=> is_term_arithmetic(argument, context), => is_term_arithmetic(argument),
} }
} }

View 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(&parameter);
}
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(&parameter, 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());
}

View File

@ -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() match open_formula.free_variable_declarations.is_empty()
{ {
true => open_formula.formula, 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)), 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() match open_formula.free_variable_declarations.is_empty()
{ {
true => open_formula.formula, 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)), Box::new(open_formula.formula)),
} }
} }

View File

@ -1,10 +1,10 @@
fn replace_variables_in_term(term: &mut foliage::Term, fn replace_variables_in_term(term: &mut crate::Term,
old_variable_declarations: &foliage::VariableDeclarations, old_variable_declarations: &crate::VariableDeclarations,
new_variable_declarations: &foliage::VariableDeclarations) new_variable_declarations: &crate::VariableDeclarations)
{ {
assert_eq!(old_variable_declarations.len(), new_variable_declarations.len()); assert_eq!(old_variable_declarations.len(), new_variable_declarations.len());
use foliage::Term; use crate::Term;
match 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, fn replace_variables_in_formula(formula: &mut crate::Formula,
old_variable_declarations: &foliage::VariableDeclarations, old_variable_declarations: &crate::VariableDeclarations,
new_variable_declarations: &foliage::VariableDeclarations) new_variable_declarations: &crate::VariableDeclarations)
{ {
use foliage::Formula; use crate::Formula;
match 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, fn replace_variable_in_term_with_term(term: &mut crate::Term,
variable_declaration: &foliage::VariableDeclaration, replacement_term: &foliage::Term) variable_declaration: &crate::VariableDeclaration, replacement_term: &crate::Term)
{ {
use foliage::Term; use crate::Term;
match 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, pub(crate) fn replace_variable_in_formula_with_term(formula: &mut crate::Formula,
variable_declaration: &foliage::VariableDeclaration, replacement_term: &foliage::Term) variable_declaration: &crate::VariableDeclaration, replacement_term: &crate::Term)
{ {
use foliage::Formula; use crate::Formula;
match 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 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) fn copy_quantified_formula(quantified_expression: &crate::QuantifiedFormula)
-> foliage::QuantifiedFormula -> crate::QuantifiedFormula
where
D: crate::traits::VariableDeclarationDomain + crate::traits::AssignVariableDeclarationDomain,
{ {
let copy_parameters = let copy_parameters =
quantified_expression.parameters.iter() quantified_expression.parameters.iter()
.map( // TODO: check correctness of clone implementation
|parameter| .map(|x| x.clone())
{
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(&copy_parameter, domain);
}
copy_parameter
})
.collect(); .collect();
let copy_parameters = std::rc::Rc::new(copy_parameters); 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, replace_variables_in_formula(&mut copy_argument, &quantified_expression.parameters,
&copy_parameters); &copy_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 pub(crate) fn copy_formula(formula: &crate::Formula) -> crate::Formula
where
D: crate::traits::VariableDeclarationDomain + crate::traits::AssignVariableDeclarationDomain,
{ {
use foliage::Formula; use crate::Formula;
match formula match formula
{ {
Formula::And(arguments) => Formula::And(arguments) =>
Formula::and(arguments.iter().map( Formula::and(arguments.iter().map(|argument| copy_formula(argument)).collect()),
|argument| copy_formula(argument, declarations)).collect()),
Formula::Boolean(value) => Formula::boolean(*value), Formula::Boolean(value) => Formula::boolean(*value),
Formula::Compare(compare) => Formula::Compare(compare) =>
Formula::compare(compare.operator, Box::new(copy_term(&compare.left)), Formula::compare(compare.operator, Box::new(copy_term(&compare.left)),
Box::new(copy_term(&compare.right))), Box::new(copy_term(&compare.right))),
Formula::Exists(quantified_formula) => 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(quantified_formula) =>
Formula::ForAll(copy_quantified_formula(quantified_formula, declarations)), Formula::ForAll(copy_quantified_formula(quantified_formula)),
Formula::IfAndOnlyIf(arguments) => Formula::IfAndOnlyIf(arguments) =>
Formula::if_and_only_if( 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) =>
Formula::implies(implies.direction, Formula::implies(implies.direction, Box::new(copy_formula(&implies.antecedent)),
Box::new(copy_formula(&implies.antecedent, declarations)), Box::new(copy_formula(&implies.implication))),
Box::new(copy_formula(&implies.implication, declarations))), Formula::Not(argument) => Formula::not(Box::new(copy_formula(&argument))),
Formula::Not(argument) => Formula::not(Box::new(copy_formula(&argument, declarations))),
Formula::Or(arguments) => Formula::Or(arguments) =>
Formula::or(arguments.iter().map( Formula::or(arguments.iter().map(|argument| copy_formula(argument)).collect()),
|argument| copy_formula(argument, declarations)).collect()),
Formula::Predicate(predicate) => Formula::Predicate(predicate) =>
Formula::predicate(std::rc::Rc::clone(&predicate.declaration), Formula::predicate(std::rc::Rc::clone(&predicate.declaration),
predicate.arguments.iter().map(|argument| copy_term(argument)).collect()), predicate.arguments.iter().map(|argument| copy_term(argument)).collect()),

View File

@ -1,8 +1,8 @@
pub(crate) fn formula_contains_predicate(formula: &foliage::Formula, pub(crate) fn formula_contains_predicate(formula: &crate::Formula,
predicate_declaration: &foliage::PredicateDeclaration) predicate_declaration: &crate::PredicateDeclaration)
-> bool -> bool
{ {
use foliage::Formula; use crate::Formula;
match 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, fn replace_predicate_in_formula(formula: &mut crate::Formula,
predicate_to_replace: &foliage::Predicate, replacement_formula: &foliage::Formula, predicate_to_replace: &crate::Predicate, replacement_formula: &crate::Formula)
declarations: &D)
where
D: crate::traits::VariableDeclarationDomain + crate::traits::AssignVariableDeclarationDomain,
{ {
use foliage::{Formula, Term}; use crate::{Formula, Term};
match formula match formula
{ {
@ -40,29 +37,27 @@ where
for mut argument in arguments for mut argument in arguments
{ {
replace_predicate_in_formula(&mut argument, predicate_to_replace, replace_predicate_in_formula(&mut argument, predicate_to_replace,
replacement_formula, declarations); replacement_formula);
}, },
Formula::Boolean(_) Formula::Boolean(_)
| Formula::Compare(_) => (), | Formula::Compare(_) => (),
Formula::Exists(quantified_expression) Formula::Exists(quantified_expression)
| Formula::ForAll(quantified_expression) => | Formula::ForAll(quantified_expression) =>
replace_predicate_in_formula(&mut quantified_expression.argument, predicate_to_replace, replace_predicate_in_formula(&mut quantified_expression.argument, predicate_to_replace,
replacement_formula, declarations), replacement_formula),
Formula::Implies(implies) => Formula::Implies(implies) =>
{ {
replace_predicate_in_formula(&mut implies.antecedent, predicate_to_replace, 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, replace_predicate_in_formula(&mut implies.implication, predicate_to_replace,
replacement_formula, declarations); replacement_formula);
}, },
Formula::Not(argument) => Formula::Not(argument) =>
replace_predicate_in_formula(argument, predicate_to_replace, replacement_formula, replace_predicate_in_formula(argument, predicate_to_replace, replacement_formula),
declarations),
Formula::Predicate(predicate) => Formula::Predicate(predicate) =>
if predicate.declaration == predicate_to_replace.declaration if predicate.declaration == predicate_to_replace.declaration
{ {
let mut replacement_formula = let mut replacement_formula = crate::utils::copy_formula(replacement_formula);
crate::utils::copy_formula(replacement_formula, declarations);
for (index, argument) in predicate.arguments.iter().enumerate() for (index, argument) in predicate.arguments.iter().enumerate()
{ {
@ -81,49 +76,49 @@ where
} }
} }
pub(crate) fn replace_predicate_in_formula_with_completed_definition<D>( pub(crate) fn replace_predicate_in_formula_with_completed_definition(
formula: &mut foliage::Formula, completed_definition: &foliage::Formula, declarations: &D) formula: &mut crate::Formula, completed_definition: &crate::Formula)
-> Result<(), crate::Error> -> 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 // TODO: refactor
let (completed_definition_predicate, completed_definition) = match completed_definition 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"); assert_eq!(arguments.len(), 2, "invalid completed definition");
match arguments[0] match arguments[0]
{ {
foliage::Formula::Predicate(ref predicate) => (predicate, &arguments[1]), Formula::Predicate(ref predicate) => (predicate, &arguments[1]),
_ => panic!("invalid completed definition"), _ => 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"),
}, },
_ => 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"); assert_eq!(arguments.len(), 2, "invalid completed definition");
match arguments[0] match arguments[0]
{ {
foliage::Formula::Predicate(ref predicate) => (predicate, &arguments[1]), Formula::Predicate(ref predicate) => (predicate, &arguments[1]),
_ => panic!("invalid completed definition"), _ => 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"),
}, },
_ => panic!("invalid completed definition"), _ => panic!("invalid completed definition"),
@ -139,8 +134,7 @@ where
std::rc::Rc::clone(&completed_definition_predicate.declaration))); std::rc::Rc::clone(&completed_definition_predicate.declaration)));
} }
replace_predicate_in_formula(formula, completed_definition_predicate, completed_definition, replace_predicate_in_formula(formula, completed_definition_predicate, completed_definition);
declarations);
Ok(()) Ok(())
} }

View File

@ -1,8 +1,8 @@
pub(crate) fn term_contains_variable(term: &foliage::Term, pub(crate) fn term_contains_variable(term: &crate::Term,
variable_declaration: &foliage::VariableDeclaration) variable_declaration: &crate::VariableDeclaration)
-> bool -> bool
{ {
use foliage::Term; use crate::Term;
match term match term
{ {