2020-02-04 16:45:06 +01:00
|
|
|
|
mod context;
|
2020-02-01 17:20:43 +01:00
|
|
|
|
mod head_type;
|
2020-01-31 17:24:13 +01:00
|
|
|
|
mod translate_body;
|
2020-01-31 17:19:44 +01:00
|
|
|
|
|
2020-02-04 16:45:06 +01:00
|
|
|
|
use context::*;
|
2020-02-01 17:20:43 +01:00
|
|
|
|
use head_type::*;
|
|
|
|
|
use translate_body::*;
|
2020-02-04 16:53:52 +01:00
|
|
|
|
use crate::traits::AssignVariableDeclarationDomain as _;
|
2020-01-25 12:55:23 +01:00
|
|
|
|
|
2020-02-02 02:53:04 +01:00
|
|
|
|
struct StatementHandler
|
|
|
|
|
{
|
|
|
|
|
context: Context,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl StatementHandler
|
|
|
|
|
{
|
|
|
|
|
fn new() -> Self
|
|
|
|
|
{
|
|
|
|
|
Self
|
|
|
|
|
{
|
|
|
|
|
context: Context::new(),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl clingo::StatementHandler for StatementHandler
|
|
|
|
|
{
|
|
|
|
|
fn on_statement(&mut self, statement: &clingo::ast::Statement) -> bool
|
|
|
|
|
{
|
|
|
|
|
match statement.statement_type()
|
|
|
|
|
{
|
|
|
|
|
clingo::ast::StatementType::Rule(ref rule) =>
|
|
|
|
|
{
|
2020-02-04 00:27:04 +01:00
|
|
|
|
if let Err(error) = read_rule(rule, &self.context)
|
2020-02-02 02:53:04 +01:00
|
|
|
|
{
|
|
|
|
|
log::error!("could not translate input program: {}", error);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
_ => log::debug!("read statement (other kind)"),
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
true
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-02-01 21:59:36 +01:00
|
|
|
|
|
2020-02-02 02:53:04 +01:00
|
|
|
|
struct Logger;
|
|
|
|
|
|
|
|
|
|
impl clingo::Logger for Logger
|
|
|
|
|
{
|
|
|
|
|
fn log(&mut self, code: clingo::Warning, message: &str)
|
|
|
|
|
{
|
|
|
|
|
log::warn!("clingo warning ({:?}): {}", code, message);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-02-05 01:10:33 +01:00
|
|
|
|
pub fn translate<P>(program_paths: &[P],
|
|
|
|
|
input_predicate_declarations: foliage::PredicateDeclarations,
|
2020-02-05 19:40:21 +01:00
|
|
|
|
input_constant_declaration_domains: crate::InputConstantDeclarationDomains,
|
2020-02-05 01:10:33 +01:00
|
|
|
|
output_format: crate::output::Format)
|
2020-02-04 00:27:04 +01:00
|
|
|
|
-> Result<(), crate::Error>
|
2020-02-02 19:20:16 +01:00
|
|
|
|
where
|
|
|
|
|
P: AsRef<std::path::Path>
|
2020-02-02 02:53:04 +01:00
|
|
|
|
{
|
|
|
|
|
let mut statement_handler = StatementHandler::new();
|
|
|
|
|
|
2020-02-05 01:10:33 +01:00
|
|
|
|
*statement_handler.context.input_predicate_declarations.borrow_mut()
|
|
|
|
|
= input_predicate_declarations.clone();
|
|
|
|
|
*statement_handler.context.predicate_declarations.borrow_mut()
|
|
|
|
|
= input_predicate_declarations;
|
2020-02-05 19:40:21 +01:00
|
|
|
|
*statement_handler.context.function_declarations.borrow_mut()
|
|
|
|
|
= input_constant_declaration_domains.keys().map(std::rc::Rc::clone).collect();
|
|
|
|
|
*statement_handler.context.input_constant_declaration_domains.borrow_mut()
|
|
|
|
|
= input_constant_declaration_domains;
|
|
|
|
|
|
|
|
|
|
for input_predicate_declaration in statement_handler.context.input_predicate_declarations
|
|
|
|
|
.borrow().iter()
|
|
|
|
|
{
|
|
|
|
|
log::info!("input predicate: {}/{}", input_predicate_declaration.name,
|
|
|
|
|
input_predicate_declaration.arity);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (input_constant_declaration, domain) in statement_handler.context
|
|
|
|
|
.input_constant_declaration_domains.borrow().iter()
|
|
|
|
|
{
|
|
|
|
|
log::info!("input constant: {} (domain: {:?})", input_constant_declaration.name, domain);
|
|
|
|
|
}
|
2020-02-05 01:10:33 +01:00
|
|
|
|
|
|
|
|
|
// Read all input programs
|
2020-02-02 19:20:16 +01:00
|
|
|
|
for program_path in program_paths
|
|
|
|
|
{
|
|
|
|
|
let program = std::fs::read_to_string(program_path.as_ref())
|
|
|
|
|
.map_err(|error| crate::Error::new_read_file(program_path.as_ref().to_path_buf(), error))?;
|
|
|
|
|
|
|
|
|
|
clingo::parse_program_with_logger(&program, &mut statement_handler, &mut Logger, std::u32::MAX)
|
|
|
|
|
.map_err(|error| crate::Error::new_translate(error))?;
|
2020-02-05 01:10:33 +01:00
|
|
|
|
|
|
|
|
|
log::info!("read input program “{}”", program_path.as_ref().display());
|
2020-02-02 19:20:16 +01:00
|
|
|
|
}
|
2020-02-02 17:57:27 +01:00
|
|
|
|
|
|
|
|
|
let context = statement_handler.context;
|
|
|
|
|
|
2020-02-03 02:57:45 +01:00
|
|
|
|
for (predicate_declaration, definitions) in context.definitions.borrow().iter()
|
2020-02-02 02:53:04 +01:00
|
|
|
|
{
|
2020-02-02 17:57:27 +01:00
|
|
|
|
for definition in definitions.definitions.iter()
|
2020-02-02 02:53:04 +01:00
|
|
|
|
{
|
2020-02-02 17:57:27 +01:00
|
|
|
|
log::debug!("definition({}/{}): {}.", predicate_declaration.name, predicate_declaration.arity,
|
2020-04-17 00:09:44 +02:00
|
|
|
|
foliage::format::display_formula(&definition.formula, &context));
|
2020-02-02 17:57:27 +01:00
|
|
|
|
}
|
2020-02-02 02:53:04 +01:00
|
|
|
|
}
|
|
|
|
|
|
2020-02-03 02:57:45 +01:00
|
|
|
|
let completed_definition = |predicate_declaration|
|
2020-02-02 03:56:34 +01:00
|
|
|
|
{
|
2020-02-03 02:57:45 +01:00
|
|
|
|
match context.definitions.borrow_mut().remove(predicate_declaration)
|
2020-02-02 17:57:27 +01:00
|
|
|
|
{
|
|
|
|
|
// This predicate symbol has at least one definition, so build the disjunction of those
|
|
|
|
|
Some(definitions) =>
|
|
|
|
|
{
|
|
|
|
|
let or_arguments = definitions.definitions.into_iter()
|
2020-02-09 04:26:24 +01:00
|
|
|
|
.map(|x| crate::existential_closure(x))
|
2020-02-02 17:57:27 +01:00
|
|
|
|
.collect::<Vec<_>>();
|
|
|
|
|
let or = foliage::Formula::or(or_arguments);
|
|
|
|
|
|
|
|
|
|
let head_arguments = definitions.head_atom_parameters.iter()
|
2020-04-17 00:09:44 +02:00
|
|
|
|
.map(|x| foliage::Term::variable(std::rc::Rc::clone(x)))
|
2020-02-02 17:57:27 +01:00
|
|
|
|
.collect::<Vec<_>>();
|
|
|
|
|
|
2020-04-17 00:09:44 +02:00
|
|
|
|
let head_predicate = foliage::Formula::predicate(
|
|
|
|
|
std::rc::Rc::clone(predicate_declaration), head_arguments);
|
2020-02-02 17:57:27 +01:00
|
|
|
|
|
2020-04-17 00:09:44 +02:00
|
|
|
|
let completed_definition =
|
|
|
|
|
foliage::Formula::if_and_only_if(vec![head_predicate, or]);
|
2020-02-02 17:57:27 +01:00
|
|
|
|
|
2020-02-04 16:45:06 +01:00
|
|
|
|
let scoped_formula = crate::ScopedFormula
|
2020-02-02 17:57:27 +01:00
|
|
|
|
{
|
|
|
|
|
free_variable_declarations: definitions.head_atom_parameters,
|
2020-04-17 03:37:53 +02:00
|
|
|
|
formula: completed_definition,
|
2020-02-02 17:57:27 +01:00
|
|
|
|
};
|
|
|
|
|
|
2020-02-09 04:26:24 +01:00
|
|
|
|
crate::universal_closure(scoped_formula)
|
2020-02-02 17:57:27 +01:00
|
|
|
|
},
|
|
|
|
|
// This predicate has no definitions, so universally falsify it
|
|
|
|
|
None =>
|
|
|
|
|
{
|
|
|
|
|
let head_atom_parameters = std::rc::Rc::new((0..predicate_declaration.arity)
|
2020-02-03 02:57:45 +01:00
|
|
|
|
.map(|_|
|
|
|
|
|
{
|
|
|
|
|
let variable_declaration = std::rc::Rc::new(
|
|
|
|
|
foliage::VariableDeclaration::new("<anonymous>".to_string()));
|
|
|
|
|
context.assign_variable_declaration_domain(&variable_declaration,
|
2020-02-04 16:45:06 +01:00
|
|
|
|
crate::Domain::Program);
|
2020-02-03 02:57:45 +01:00
|
|
|
|
variable_declaration
|
|
|
|
|
})
|
2020-02-02 17:57:27 +01:00
|
|
|
|
.collect::<Vec<_>>());
|
|
|
|
|
|
|
|
|
|
let head_arguments = head_atom_parameters.iter()
|
2020-04-17 00:09:44 +02:00
|
|
|
|
.map(|x| foliage::Term::variable(std::rc::Rc::clone(x)))
|
2020-02-02 17:57:27 +01:00
|
|
|
|
.collect();
|
|
|
|
|
|
2020-04-17 00:09:44 +02:00
|
|
|
|
let head_predicate = foliage::Formula::predicate(
|
|
|
|
|
std::rc::Rc::clone(predicate_declaration), head_arguments);
|
2020-02-02 17:57:27 +01:00
|
|
|
|
|
|
|
|
|
let not = foliage::Formula::not(Box::new(head_predicate));
|
|
|
|
|
|
2020-02-04 16:45:06 +01:00
|
|
|
|
let scoped_formula = crate::ScopedFormula
|
2020-02-02 17:57:27 +01:00
|
|
|
|
{
|
|
|
|
|
free_variable_declarations: head_atom_parameters,
|
2020-04-17 03:37:53 +02:00
|
|
|
|
formula: not,
|
2020-02-02 17:57:27 +01:00
|
|
|
|
};
|
|
|
|
|
|
2020-02-09 04:26:24 +01:00
|
|
|
|
crate::universal_closure(scoped_formula)
|
2020-02-02 17:57:27 +01:00
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2020-02-03 02:57:45 +01:00
|
|
|
|
let predicate_declarations = context.predicate_declarations.borrow();
|
2020-02-05 02:14:47 +01:00
|
|
|
|
let function_declarations = context.function_declarations.borrow();
|
2020-02-05 20:19:22 +01:00
|
|
|
|
let input_constant_declaration_domains = context.input_constant_declaration_domains.borrow();
|
2020-02-02 17:57:27 +01:00
|
|
|
|
let completed_definitions = predicate_declarations.iter()
|
2020-02-05 01:10:33 +01:00
|
|
|
|
// Don’t perform completion for any input predicate
|
|
|
|
|
.filter(|x| !context.input_predicate_declarations.borrow().contains(*x))
|
2020-02-02 17:57:27 +01:00
|
|
|
|
.map(|x| (std::rc::Rc::clone(x), completed_definition(x)));
|
|
|
|
|
|
2020-02-04 00:27:04 +01:00
|
|
|
|
// Earlier log messages may have assigned IDs to the variable declarations, so reset them
|
2020-02-05 18:50:48 +01:00
|
|
|
|
context.program_variable_declaration_ids.borrow_mut().clear();
|
|
|
|
|
context.integer_variable_declaration_ids.borrow_mut().clear();
|
2020-02-02 17:57:27 +01:00
|
|
|
|
|
2020-02-05 02:14:47 +01:00
|
|
|
|
let print_title = |title, section_separator|
|
|
|
|
|
{
|
|
|
|
|
print!("{}{}", section_separator, "%".repeat(80));
|
|
|
|
|
print!("\n% {}", title);
|
|
|
|
|
println!("\n{}", "%".repeat(80));
|
|
|
|
|
};
|
|
|
|
|
|
2020-02-05 01:10:33 +01:00
|
|
|
|
let print_formula = |formula: &foliage::Formula|
|
2020-02-02 17:57:27 +01:00
|
|
|
|
{
|
2020-02-05 01:10:33 +01:00
|
|
|
|
match output_format
|
2020-02-04 00:27:04 +01:00
|
|
|
|
{
|
2020-02-05 01:10:33 +01:00
|
|
|
|
crate::output::Format::HumanReadable => print!("{}",
|
2020-04-17 00:09:44 +02:00
|
|
|
|
foliage::format::display_formula(formula, &context)),
|
2020-02-05 01:10:33 +01:00
|
|
|
|
crate::output::Format::TPTP => print!("{}",
|
|
|
|
|
crate::output::tptp::display_formula(formula, &context)),
|
|
|
|
|
}
|
|
|
|
|
};
|
2020-02-04 00:27:04 +01:00
|
|
|
|
|
2020-02-05 01:10:33 +01:00
|
|
|
|
let mut section_separator = "";
|
2020-02-04 00:27:04 +01:00
|
|
|
|
|
2020-02-05 02:14:47 +01:00
|
|
|
|
if output_format == crate::output::Format::TPTP
|
|
|
|
|
{
|
|
|
|
|
print_title("anthem types", section_separator);
|
|
|
|
|
section_separator = "\n";
|
|
|
|
|
|
|
|
|
|
let tptp_preamble_anthem_types
|
|
|
|
|
= include_str!("../output/tptp/preamble_types.tptp").trim_end();
|
|
|
|
|
println!("{}", tptp_preamble_anthem_types);
|
|
|
|
|
|
|
|
|
|
print_title("anthem axioms", section_separator);
|
|
|
|
|
|
|
|
|
|
let tptp_preamble_anthem_types
|
|
|
|
|
= include_str!("../output/tptp/preamble_axioms.tptp").trim_end();
|
|
|
|
|
println!("{}", tptp_preamble_anthem_types);
|
|
|
|
|
|
|
|
|
|
if !predicate_declarations.is_empty() || !function_declarations.is_empty()
|
|
|
|
|
{
|
|
|
|
|
print_title("types", section_separator);
|
|
|
|
|
|
|
|
|
|
if !predicate_declarations.is_empty()
|
|
|
|
|
{
|
|
|
|
|
println!("% predicate types")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for predicate_declaration in &*predicate_declarations
|
|
|
|
|
{
|
|
|
|
|
println!("tff(type, type, {}).",
|
|
|
|
|
crate::output::tptp::display_predicate_declaration(predicate_declaration));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if !function_declarations.is_empty()
|
|
|
|
|
{
|
|
|
|
|
println!("% function types")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for function_declaration in &*function_declarations
|
|
|
|
|
{
|
|
|
|
|
println!("tff(type, type, {}).",
|
|
|
|
|
crate::output::tptp::display_function_declaration(function_declaration,
|
|
|
|
|
&context));
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-02-05 20:19:22 +01:00
|
|
|
|
|
|
|
|
|
let symbolic_constants = function_declarations.iter().filter(
|
|
|
|
|
|x| !input_constant_declaration_domains.contains_key(*x));
|
|
|
|
|
|
|
|
|
|
let mut last_symbolic_constant: Option<std::rc::Rc<foliage::FunctionDeclaration>> = None;
|
|
|
|
|
|
|
|
|
|
for (i, symbolic_constant) in symbolic_constants.enumerate()
|
|
|
|
|
{
|
|
|
|
|
// Order axioms are only necessary with two or more symbolic constants
|
|
|
|
|
if i == 1
|
|
|
|
|
{
|
|
|
|
|
println!("% axioms for order of symbolic constants")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if symbolic_constant.arity > 0
|
|
|
|
|
{
|
|
|
|
|
return Err(crate::Error::new_logic("unexpected n-ary function declaration"));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if let Some(last_symbolic_constant) = last_symbolic_constant
|
|
|
|
|
{
|
|
|
|
|
println!("tff(symbolic_constant_order, axiom, p__less__({}, {})).",
|
|
|
|
|
last_symbolic_constant.name, symbolic_constant.name);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
last_symbolic_constant = Some(std::rc::Rc::clone(symbolic_constant));
|
|
|
|
|
}
|
2020-02-05 02:14:47 +01:00
|
|
|
|
}
|
|
|
|
|
|
2020-02-05 01:10:33 +01:00
|
|
|
|
for (i, (predicate_declaration, completed_definition)) in completed_definitions.enumerate()
|
|
|
|
|
{
|
|
|
|
|
if i == 0
|
|
|
|
|
{
|
2020-02-05 02:14:47 +01:00
|
|
|
|
print_title("completed definitions", section_separator);
|
2020-02-05 01:10:33 +01:00
|
|
|
|
}
|
2020-02-04 00:27:04 +01:00
|
|
|
|
|
2020-02-05 02:14:47 +01:00
|
|
|
|
section_separator = "\n";
|
|
|
|
|
|
|
|
|
|
println!("% completed definition of {}/{}", predicate_declaration.name,
|
2020-02-05 01:10:33 +01:00
|
|
|
|
predicate_declaration.arity);
|
2020-02-04 00:27:04 +01:00
|
|
|
|
|
2020-02-05 01:10:33 +01:00
|
|
|
|
if output_format == crate::output::Format::TPTP
|
2020-02-04 00:27:04 +01:00
|
|
|
|
{
|
2020-02-05 01:10:33 +01:00
|
|
|
|
print!("tff(completion_{}_{}, axiom, ", predicate_declaration.name,
|
|
|
|
|
predicate_declaration.arity);
|
|
|
|
|
}
|
2020-02-04 00:27:04 +01:00
|
|
|
|
|
2020-02-05 01:10:33 +01:00
|
|
|
|
print_formula(&completed_definition);
|
2020-02-04 00:27:04 +01:00
|
|
|
|
|
2020-02-05 01:10:33 +01:00
|
|
|
|
if output_format == crate::output::Format::TPTP
|
|
|
|
|
{
|
|
|
|
|
print!(").");
|
|
|
|
|
}
|
2020-02-04 00:27:04 +01:00
|
|
|
|
|
2020-02-05 01:10:33 +01:00
|
|
|
|
println!("");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (i, integrity_constraint) in context.integrity_constraints.borrow().iter().enumerate()
|
|
|
|
|
{
|
|
|
|
|
if i == 0
|
|
|
|
|
{
|
2020-02-05 02:14:47 +01:00
|
|
|
|
print_title("integrity constraints", section_separator);
|
2020-02-05 01:10:33 +01:00
|
|
|
|
}
|
|
|
|
|
|
2020-02-05 02:14:47 +01:00
|
|
|
|
section_separator = "\n";
|
|
|
|
|
|
2020-02-05 01:10:33 +01:00
|
|
|
|
if output_format == crate::output::Format::TPTP
|
|
|
|
|
{
|
|
|
|
|
print!("tff(integrity_constraint, axiom, ");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
print_formula(&integrity_constraint);
|
|
|
|
|
|
|
|
|
|
if output_format == crate::output::Format::TPTP
|
|
|
|
|
{
|
|
|
|
|
print!(").");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
println!("");
|
2020-02-02 17:57:27 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Ok(())
|
2020-02-02 03:56:34 +01:00
|
|
|
|
}
|
|
|
|
|
|
2020-02-04 00:27:04 +01:00
|
|
|
|
fn read_rule(rule: &clingo::ast::Rule, context: &Context) -> Result<(), crate::Error>
|
2020-02-02 02:53:04 +01:00
|
|
|
|
{
|
2020-02-03 02:57:45 +01:00
|
|
|
|
let head_type = determine_head_type(rule.head(), context)?;
|
2020-02-01 19:20:46 +01:00
|
|
|
|
|
2020-02-02 03:56:34 +01:00
|
|
|
|
match &head_type
|
2020-02-01 15:32:41 +01:00
|
|
|
|
{
|
2020-02-02 03:56:34 +01:00
|
|
|
|
HeadType::SingleAtom(head_atom)
|
|
|
|
|
| HeadType::ChoiceWithSingleAtom(head_atom) =>
|
2020-02-01 19:20:46 +01:00
|
|
|
|
{
|
2020-02-03 02:57:45 +01:00
|
|
|
|
if !context.definitions.borrow().contains_key(&head_atom.predicate_declaration)
|
2020-02-01 19:20:46 +01:00
|
|
|
|
{
|
2020-02-02 17:57:27 +01:00
|
|
|
|
let head_atom_parameters = std::rc::Rc::new((0..head_atom.predicate_declaration.arity)
|
2020-02-03 02:57:45 +01:00
|
|
|
|
.map(|_|
|
|
|
|
|
{
|
|
|
|
|
let variable_declaration = std::rc::Rc::new(
|
|
|
|
|
foliage::VariableDeclaration::new("<anonymous>".to_string()));
|
|
|
|
|
context.assign_variable_declaration_domain(&variable_declaration,
|
2020-02-04 16:45:06 +01:00
|
|
|
|
crate::Domain::Program);
|
2020-02-03 02:57:45 +01:00
|
|
|
|
variable_declaration
|
|
|
|
|
})
|
2020-02-02 17:57:27 +01:00
|
|
|
|
.collect());
|
|
|
|
|
|
2020-02-03 02:57:45 +01:00
|
|
|
|
context.definitions.borrow_mut().insert(
|
|
|
|
|
std::rc::Rc::clone(&head_atom.predicate_declaration),
|
2020-02-01 19:20:46 +01:00
|
|
|
|
Definitions
|
|
|
|
|
{
|
2020-02-02 17:57:27 +01:00
|
|
|
|
head_atom_parameters,
|
2020-02-01 19:20:46 +01:00
|
|
|
|
definitions: vec![],
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2020-02-03 02:57:45 +01:00
|
|
|
|
let mut definitions = context.definitions.borrow_mut();
|
|
|
|
|
let definitions = definitions.get_mut(&head_atom.predicate_declaration).unwrap();
|
2020-02-01 21:59:36 +01:00
|
|
|
|
|
2020-02-03 02:57:45 +01:00
|
|
|
|
let head_atom_parameters = std::rc::Rc::clone(&definitions.head_atom_parameters);
|
2020-04-17 03:28:18 +02:00
|
|
|
|
let free_variable_declarations = std::cell::RefCell::new(vec![]);
|
|
|
|
|
let free_layer =
|
|
|
|
|
foliage::VariableDeclarationStackLayer::Free(free_variable_declarations);
|
|
|
|
|
let head_atom_parameters_layer = foliage::VariableDeclarationStackLayer::bound(
|
|
|
|
|
&free_layer, head_atom_parameters);
|
2020-02-01 21:59:36 +01:00
|
|
|
|
|
2020-04-17 03:28:18 +02:00
|
|
|
|
let mut definition_arguments = translate_body(rule.body(), context,
|
|
|
|
|
&head_atom_parameters_layer)?;
|
2020-02-02 02:32:32 +01:00
|
|
|
|
|
|
|
|
|
assert_eq!(definitions.head_atom_parameters.len(), head_atom.arguments.len());
|
|
|
|
|
|
2020-02-02 03:56:34 +01:00
|
|
|
|
if let HeadType::ChoiceWithSingleAtom(_) = head_type
|
|
|
|
|
{
|
|
|
|
|
let head_arguments = definitions.head_atom_parameters.iter()
|
2020-04-17 00:09:44 +02:00
|
|
|
|
.map(|x| foliage::Term::variable(std::rc::Rc::clone(x)))
|
2020-02-02 03:56:34 +01:00
|
|
|
|
.collect::<Vec<_>>();
|
|
|
|
|
|
2020-04-17 00:09:44 +02:00
|
|
|
|
let head_predicate = foliage::Formula::predicate(
|
|
|
|
|
std::rc::Rc::clone(&head_atom.predicate_declaration), head_arguments);
|
2020-02-02 03:56:34 +01:00
|
|
|
|
|
2020-04-17 00:09:44 +02:00
|
|
|
|
definition_arguments.push(head_predicate);
|
2020-02-02 03:56:34 +01:00
|
|
|
|
}
|
|
|
|
|
|
2020-02-02 02:32:32 +01:00
|
|
|
|
let mut head_atom_arguments_iterator = head_atom.arguments.iter();
|
|
|
|
|
|
|
|
|
|
for head_atom_parameter in definitions.head_atom_parameters.iter()
|
|
|
|
|
{
|
|
|
|
|
let head_atom_argument = head_atom_arguments_iterator.next().unwrap();
|
|
|
|
|
|
|
|
|
|
let translated_head_term = crate::translate::common::choose_value_in_term(
|
2020-04-17 03:28:18 +02:00
|
|
|
|
head_atom_argument, std::rc::Rc::clone(head_atom_parameter), context,
|
|
|
|
|
&head_atom_parameters_layer)?;
|
2020-02-02 02:32:32 +01:00
|
|
|
|
|
2020-04-17 00:09:44 +02:00
|
|
|
|
definition_arguments.push(translated_head_term);
|
2020-02-02 02:32:32 +01:00
|
|
|
|
}
|
2020-02-01 21:59:36 +01:00
|
|
|
|
|
2020-04-17 03:28:18 +02:00
|
|
|
|
// TODO: refactor
|
|
|
|
|
let free_variable_declarations = match free_layer
|
|
|
|
|
{
|
|
|
|
|
foliage::VariableDeclarationStackLayer::Free(free_variable_declarations)
|
|
|
|
|
=> free_variable_declarations.into_inner(),
|
|
|
|
|
_ => unreachable!(),
|
|
|
|
|
};
|
2020-02-02 02:32:32 +01:00
|
|
|
|
|
2020-02-02 17:57:27 +01:00
|
|
|
|
let definition = match definition_arguments.len()
|
|
|
|
|
{
|
|
|
|
|
1 => definition_arguments.pop().unwrap(),
|
2020-04-17 00:09:44 +02:00
|
|
|
|
0 => foliage::Formula::true_(),
|
|
|
|
|
_ => foliage::Formula::and(definition_arguments),
|
2020-02-02 17:57:27 +01:00
|
|
|
|
};
|
2020-02-02 02:32:32 +01:00
|
|
|
|
|
2020-02-04 16:45:06 +01:00
|
|
|
|
let definition = crate::ScopedFormula
|
2020-02-02 02:32:32 +01:00
|
|
|
|
{
|
2020-02-02 17:57:27 +01:00
|
|
|
|
free_variable_declarations: std::rc::Rc::new(free_variable_declarations),
|
2020-04-17 03:37:53 +02:00
|
|
|
|
formula: definition,
|
2020-02-02 02:32:32 +01:00
|
|
|
|
};
|
|
|
|
|
|
2020-02-04 00:27:04 +01:00
|
|
|
|
log::debug!("translated rule with single atom in head: {}",
|
2020-04-17 00:09:44 +02:00
|
|
|
|
foliage::format::display_formula(&definition.formula, context));
|
2020-02-02 02:32:32 +01:00
|
|
|
|
|
|
|
|
|
definitions.definitions.push(definition);
|
2020-02-01 19:20:46 +01:00
|
|
|
|
},
|
2020-02-01 17:20:43 +01:00
|
|
|
|
HeadType::IntegrityConstraint =>
|
2020-02-02 03:56:34 +01:00
|
|
|
|
{
|
2020-04-17 03:28:18 +02:00
|
|
|
|
let free_variable_declarations = std::cell::RefCell::new(vec![]);
|
|
|
|
|
let free_layer =
|
|
|
|
|
foliage::VariableDeclarationStackLayer::Free(free_variable_declarations);
|
|
|
|
|
|
|
|
|
|
let mut arguments = translate_body(rule.body(), context, &free_layer)?;
|
2020-02-02 03:56:34 +01:00
|
|
|
|
|
2020-04-17 03:28:18 +02:00
|
|
|
|
// TODO: refactor
|
|
|
|
|
let free_variable_declarations = match free_layer
|
|
|
|
|
{
|
|
|
|
|
foliage::VariableDeclarationStackLayer::Free(free_variable_declarations)
|
|
|
|
|
=> free_variable_declarations.into_inner(),
|
|
|
|
|
_ => unreachable!(),
|
|
|
|
|
};
|
2020-02-02 03:56:34 +01:00
|
|
|
|
|
2020-02-02 17:57:27 +01:00
|
|
|
|
let formula = match arguments.len()
|
|
|
|
|
{
|
2020-04-17 00:09:44 +02:00
|
|
|
|
1 => foliage::Formula::not(Box::new(arguments.pop().unwrap())),
|
2020-02-02 17:57:27 +01:00
|
|
|
|
0 => foliage::Formula::false_(),
|
|
|
|
|
_ => foliage::Formula::not(Box::new(foliage::Formula::and(arguments))),
|
|
|
|
|
};
|
|
|
|
|
|
2020-02-04 16:45:06 +01:00
|
|
|
|
let scoped_formula = crate::ScopedFormula
|
2020-02-02 03:56:34 +01:00
|
|
|
|
{
|
2020-02-02 17:57:27 +01:00
|
|
|
|
free_variable_declarations: std::rc::Rc::new(free_variable_declarations),
|
2020-04-17 03:37:53 +02:00
|
|
|
|
formula,
|
2020-02-02 03:56:34 +01:00
|
|
|
|
};
|
|
|
|
|
|
2020-02-09 04:26:24 +01:00
|
|
|
|
let integrity_constraint = crate::universal_closure(scoped_formula);
|
2020-02-02 03:56:34 +01:00
|
|
|
|
|
2020-02-04 00:27:04 +01:00
|
|
|
|
log::debug!("translated integrity constraint: {}",
|
2020-04-17 00:09:44 +02:00
|
|
|
|
foliage::format::display_formula(&integrity_constraint, context));
|
2020-02-02 03:56:34 +01:00
|
|
|
|
|
2020-02-03 02:57:45 +01:00
|
|
|
|
context.integrity_constraints.borrow_mut().push(integrity_constraint);
|
2020-02-02 03:56:34 +01:00
|
|
|
|
},
|
|
|
|
|
HeadType::Trivial => log::info!("skipping trivial rule"),
|
2020-02-01 15:32:41 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Ok(())
|
2020-01-24 13:32:43 +01:00
|
|
|
|
}
|