Add option for input predicates
This commit is contained in:
parent
6d489e457f
commit
caab0a618e
@ -8,6 +8,7 @@ pub enum Kind
|
|||||||
DecodeIdentifier,
|
DecodeIdentifier,
|
||||||
Translate,
|
Translate,
|
||||||
ReadFile(std::path::PathBuf),
|
ReadFile(std::path::PathBuf),
|
||||||
|
ParsePredicateDeclaration,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Error
|
pub struct Error
|
||||||
@ -62,6 +63,11 @@ impl Error
|
|||||||
{
|
{
|
||||||
Self::new(Kind::ReadFile(path)).with(source)
|
Self::new(Kind::ReadFile(path)).with(source)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn new_parse_predicate_declaration() -> Self
|
||||||
|
{
|
||||||
|
Self::new(Kind::ParsePredicateDeclaration)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::fmt::Debug for Error
|
impl std::fmt::Debug for Error
|
||||||
@ -79,6 +85,8 @@ impl std::fmt::Debug for Error
|
|||||||
Kind::DecodeIdentifier => write!(formatter, "could not decode identifier"),
|
Kind::DecodeIdentifier => write!(formatter, "could not decode identifier"),
|
||||||
Kind::Translate => write!(formatter, "could not translate input program"),
|
Kind::Translate => write!(formatter, "could not translate input program"),
|
||||||
Kind::ReadFile(path) => write!(formatter, "could not read file “{}”", path.display()),
|
Kind::ReadFile(path) => write!(formatter, "could not read file “{}”", path.display()),
|
||||||
|
Kind::ParsePredicateDeclaration => write!(formatter,
|
||||||
|
"could not parse predicate declaration"),
|
||||||
}?;
|
}?;
|
||||||
|
|
||||||
if let Some(source) = &self.source
|
if let Some(source) = &self.source
|
||||||
|
@ -8,3 +8,4 @@ mod utils;
|
|||||||
|
|
||||||
pub use error::Error;
|
pub use error::Error;
|
||||||
pub(crate) use utils::*;
|
pub(crate) use utils::*;
|
||||||
|
pub use utils::parse_predicate_declaration;
|
||||||
|
@ -14,6 +14,10 @@ enum Command
|
|||||||
/// Output format (human-readable, tptp)
|
/// Output format (human-readable, tptp)
|
||||||
#[structopt(long, default_value = "human-readable")]
|
#[structopt(long, default_value = "human-readable")]
|
||||||
output_format: anthem::output::Format,
|
output_format: anthem::output::Format,
|
||||||
|
|
||||||
|
/// Input predicates (examples: p/0, q/2)
|
||||||
|
#[structopt(long, parse(try_from_str = anthem::parse_predicate_declaration))]
|
||||||
|
input_predicates: Vec<std::rc::Rc<foliage::PredicateDeclaration>>,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -29,10 +33,12 @@ fn main()
|
|||||||
{
|
{
|
||||||
input,
|
input,
|
||||||
output_format,
|
output_format,
|
||||||
|
input_predicates,
|
||||||
}
|
}
|
||||||
=>
|
=>
|
||||||
{
|
{
|
||||||
if let Err(error) = anthem::translate::verify_properties::translate(&input,
|
if let Err(error) = anthem::translate::verify_properties::translate(&input,
|
||||||
|
input_predicates.into_iter().collect::<foliage::PredicateDeclarations>(),
|
||||||
output_format)
|
output_format)
|
||||||
{
|
{
|
||||||
log::error!("could not translate input program: {}", error);
|
log::error!("could not translate input program: {}", error);
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
pub(crate) mod human_readable;
|
pub(crate) mod human_readable;
|
||||||
pub(crate) mod tptp;
|
pub(crate) mod tptp;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
|
||||||
pub enum Format
|
pub enum Format
|
||||||
{
|
{
|
||||||
HumanReadable,
|
HumanReadable,
|
||||||
|
@ -54,13 +54,21 @@ impl clingo::Logger for Logger
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn translate<P>(program_paths: &[P], output_format: crate::output::Format)
|
pub fn translate<P>(program_paths: &[P],
|
||||||
|
input_predicate_declarations: foliage::PredicateDeclarations,
|
||||||
|
output_format: crate::output::Format)
|
||||||
-> Result<(), crate::Error>
|
-> Result<(), crate::Error>
|
||||||
where
|
where
|
||||||
P: AsRef<std::path::Path>
|
P: AsRef<std::path::Path>
|
||||||
{
|
{
|
||||||
let mut statement_handler = StatementHandler::new();
|
let mut statement_handler = StatementHandler::new();
|
||||||
|
|
||||||
|
*statement_handler.context.input_predicate_declarations.borrow_mut()
|
||||||
|
= input_predicate_declarations.clone();
|
||||||
|
*statement_handler.context.predicate_declarations.borrow_mut()
|
||||||
|
= input_predicate_declarations;
|
||||||
|
|
||||||
|
// Read all input programs
|
||||||
for program_path in program_paths
|
for program_path in program_paths
|
||||||
{
|
{
|
||||||
let program = std::fs::read_to_string(program_path.as_ref())
|
let program = std::fs::read_to_string(program_path.as_ref())
|
||||||
@ -68,6 +76,8 @@ where
|
|||||||
|
|
||||||
clingo::parse_program_with_logger(&program, &mut statement_handler, &mut Logger, std::u32::MAX)
|
clingo::parse_program_with_logger(&program, &mut statement_handler, &mut Logger, std::u32::MAX)
|
||||||
.map_err(|error| crate::Error::new_translate(error))?;
|
.map_err(|error| crate::Error::new_translate(error))?;
|
||||||
|
|
||||||
|
log::info!("read input program “{}”", program_path.as_ref().display());
|
||||||
}
|
}
|
||||||
|
|
||||||
let context = statement_handler.context;
|
let context = statement_handler.context;
|
||||||
@ -147,71 +157,78 @@ where
|
|||||||
|
|
||||||
let predicate_declarations = context.predicate_declarations.borrow();
|
let predicate_declarations = context.predicate_declarations.borrow();
|
||||||
let completed_definitions = predicate_declarations.iter()
|
let completed_definitions = predicate_declarations.iter()
|
||||||
|
// Don’t perform completion for any input predicate
|
||||||
|
.filter(|x| !context.input_predicate_declarations.borrow().contains(*x))
|
||||||
.map(|x| (std::rc::Rc::clone(x), completed_definition(x)));
|
.map(|x| (std::rc::Rc::clone(x), completed_definition(x)));
|
||||||
|
|
||||||
// Earlier log messages may have assigned IDs to the variable declarations, so reset them
|
// Earlier log messages may have assigned IDs to the variable declarations, so reset them
|
||||||
context.variable_declaration_ids.borrow_mut().clear();
|
context.variable_declaration_ids.borrow_mut().clear();
|
||||||
|
|
||||||
|
let print_formula = |formula: &foliage::Formula|
|
||||||
|
{
|
||||||
match output_format
|
match output_format
|
||||||
{
|
{
|
||||||
crate::output::Format::HumanReadable =>
|
crate::output::Format::HumanReadable => print!("{}",
|
||||||
{
|
crate::output::human_readable::display_formula(formula, None, &context)),
|
||||||
|
crate::output::Format::TPTP => print!("{}",
|
||||||
|
crate::output::tptp::display_formula(formula, &context)),
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
let mut section_separator = "";
|
let mut section_separator = "";
|
||||||
|
|
||||||
if !predicate_declarations.is_empty()
|
for (i, (predicate_declaration, completed_definition)) in completed_definitions.enumerate()
|
||||||
|
{
|
||||||
|
if i == 0
|
||||||
{
|
{
|
||||||
println!("{}% completed definitions", section_separator);
|
println!("{}% completed definitions", section_separator);
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("%% completed definition of {}/{}", predicate_declaration.name,
|
||||||
|
predicate_declaration.arity);
|
||||||
|
|
||||||
|
if output_format == crate::output::Format::TPTP
|
||||||
|
{
|
||||||
|
print!("tff(completion_{}_{}, axiom, ", predicate_declaration.name,
|
||||||
|
predicate_declaration.arity);
|
||||||
|
}
|
||||||
|
|
||||||
|
print_formula(&completed_definition);
|
||||||
|
|
||||||
|
if output_format == crate::output::Format::TPTP
|
||||||
|
{
|
||||||
|
print!(").");
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("");
|
||||||
|
|
||||||
section_separator = "\n";
|
section_separator = "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
for (predicate_declaration, completed_definition) in completed_definitions
|
for (i, integrity_constraint) in context.integrity_constraints.borrow().iter().enumerate()
|
||||||
{
|
{
|
||||||
println!("%% completed definition of {}/{}\n{}", predicate_declaration.name,
|
if i == 0
|
||||||
predicate_declaration.arity, crate::output::human_readable::display_formula(
|
|
||||||
&completed_definition, None, &context));
|
|
||||||
}
|
|
||||||
|
|
||||||
if !context.integrity_constraints.borrow().is_empty()
|
|
||||||
{
|
{
|
||||||
println!("{}% integrity constraints", section_separator);
|
println!("{}% integrity constraints", section_separator);
|
||||||
}
|
}
|
||||||
|
|
||||||
for integrity_constraint in context.integrity_constraints.borrow().iter()
|
if output_format == crate::output::Format::TPTP
|
||||||
{
|
{
|
||||||
println!("{}", crate::output::human_readable::display_formula(
|
print!("tff(integrity_constraint, axiom, ");
|
||||||
&integrity_constraint, None, &context));
|
|
||||||
}
|
}
|
||||||
},
|
|
||||||
crate::output::Format::TPTP =>
|
|
||||||
{
|
|
||||||
let mut section_separator = "";
|
|
||||||
|
|
||||||
if !predicate_declarations.is_empty()
|
print_formula(&integrity_constraint);
|
||||||
|
|
||||||
|
if output_format == crate::output::Format::TPTP
|
||||||
{
|
{
|
||||||
println!("{}% completed definitions", section_separator);
|
print!(").");
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("");
|
||||||
|
|
||||||
section_separator = "\n";
|
section_separator = "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
for (predicate_declaration, completed_definition) in completed_definitions
|
|
||||||
{
|
|
||||||
println!("tff(completion_{}_{}, axiom, {}).", predicate_declaration.name,
|
|
||||||
predicate_declaration.arity, crate::output::tptp::display_formula(
|
|
||||||
&completed_definition, &context));
|
|
||||||
}
|
|
||||||
|
|
||||||
if !context.integrity_constraints.borrow().is_empty()
|
|
||||||
{
|
|
||||||
println!("{}% integrity constraints", section_separator);
|
|
||||||
}
|
|
||||||
|
|
||||||
for integrity_constraint in context.integrity_constraints.borrow().iter()
|
|
||||||
{
|
|
||||||
println!("tff(integrity_constraint, axiom, {}).",
|
|
||||||
crate::output::tptp::display_formula(&integrity_constraint, &context));
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,6 +20,8 @@ pub(crate) struct Context
|
|||||||
pub integrity_constraints: std::cell::RefCell<foliage::Formulas>,
|
pub integrity_constraints: std::cell::RefCell<foliage::Formulas>,
|
||||||
|
|
||||||
pub input_constant_declaration_domains: std::cell::RefCell<InputConstantDeclarationDomains>,
|
pub input_constant_declaration_domains: std::cell::RefCell<InputConstantDeclarationDomains>,
|
||||||
|
pub input_predicate_declarations: std::cell::RefCell<foliage::PredicateDeclarations>,
|
||||||
|
|
||||||
pub function_declarations: std::cell::RefCell<foliage::FunctionDeclarations>,
|
pub function_declarations: std::cell::RefCell<foliage::FunctionDeclarations>,
|
||||||
pub predicate_declarations: std::cell::RefCell<foliage::PredicateDeclarations>,
|
pub predicate_declarations: std::cell::RefCell<foliage::PredicateDeclarations>,
|
||||||
pub variable_declaration_stack: std::cell::RefCell<foliage::VariableDeclarationStack>,
|
pub variable_declaration_stack: std::cell::RefCell<foliage::VariableDeclarationStack>,
|
||||||
@ -38,6 +40,9 @@ impl Context
|
|||||||
|
|
||||||
input_constant_declaration_domains:
|
input_constant_declaration_domains:
|
||||||
std::cell::RefCell::new(InputConstantDeclarationDomains::new()),
|
std::cell::RefCell::new(InputConstantDeclarationDomains::new()),
|
||||||
|
input_predicate_declarations:
|
||||||
|
std::cell::RefCell::new(foliage::PredicateDeclarations::new()),
|
||||||
|
|
||||||
function_declarations: std::cell::RefCell::new(foliage::FunctionDeclarations::new()),
|
function_declarations: std::cell::RefCell::new(foliage::FunctionDeclarations::new()),
|
||||||
predicate_declarations: std::cell::RefCell::new(foliage::PredicateDeclarations::new()),
|
predicate_declarations: std::cell::RefCell::new(foliage::PredicateDeclarations::new()),
|
||||||
variable_declaration_stack:
|
variable_declaration_stack:
|
||||||
|
32
src/utils.rs
32
src/utils.rs
@ -21,3 +21,35 @@ pub(crate) struct ScopedFormula
|
|||||||
pub free_variable_declarations: std::rc::Rc<foliage::VariableDeclarations>,
|
pub free_variable_declarations: std::rc::Rc<foliage::VariableDeclarations>,
|
||||||
pub formula: Box<foliage::Formula>,
|
pub formula: Box<foliage::Formula>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn parse_predicate_declaration(input: &str)
|
||||||
|
-> Result<std::rc::Rc<foliage::PredicateDeclaration>, crate::Error>
|
||||||
|
{
|
||||||
|
let mut parts = input.split("/");
|
||||||
|
|
||||||
|
let name = match parts.next()
|
||||||
|
{
|
||||||
|
Some(name) => name.to_string(),
|
||||||
|
None => return Err(crate::Error::new_parse_predicate_declaration()),
|
||||||
|
};
|
||||||
|
|
||||||
|
use std::str::FromStr;
|
||||||
|
|
||||||
|
let arity = match parts.next()
|
||||||
|
{
|
||||||
|
Some(arity)
|
||||||
|
=> usize::from_str(arity).map_err(|_| crate::Error::new_parse_predicate_declaration())?,
|
||||||
|
None => return Err(crate::Error::new_parse_predicate_declaration()),
|
||||||
|
};
|
||||||
|
|
||||||
|
if parts.next().is_some()
|
||||||
|
{
|
||||||
|
return Err(crate::Error::new_parse_predicate_declaration());
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(std::rc::Rc::new(foliage::PredicateDeclaration
|
||||||
|
{
|
||||||
|
name,
|
||||||
|
arity,
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user