Persist declarations between rules
This commit is contained in:
parent
99345bc0ac
commit
23641987bc
45
src/main.rs
45
src/main.rs
@ -1,36 +1,3 @@
|
|||||||
struct StatementHandler;
|
|
||||||
|
|
||||||
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) =>
|
|
||||||
{
|
|
||||||
if let Err(error) = anthem::translate::verify_properties::read(rule)
|
|
||||||
{
|
|
||||||
log::error!("could not translate input program: {}", error);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
_ => log::debug!("read statement (other kind)"),
|
|
||||||
}
|
|
||||||
|
|
||||||
true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct Logger;
|
|
||||||
|
|
||||||
impl clingo::Logger for Logger
|
|
||||||
{
|
|
||||||
fn log(&mut self, code: clingo::Warning, message: &str)
|
|
||||||
{
|
|
||||||
log::warn!("clingo warning ({:?}): {}", code, message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main()
|
fn main()
|
||||||
{
|
{
|
||||||
pretty_env_logger::init();
|
pretty_env_logger::init();
|
||||||
@ -45,15 +12,5 @@ fn main()
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut statement_handler = StatementHandler{};
|
std::process::exit(anthem::translate::verify_properties::translate(&program));
|
||||||
|
|
||||||
match clingo::parse_program_with_logger(&program, &mut statement_handler, &mut Logger, std::u32::MAX)
|
|
||||||
{
|
|
||||||
Ok(()) => (),
|
|
||||||
Err(error) =>
|
|
||||||
{
|
|
||||||
log::error!("could not translate input program: {}", error);
|
|
||||||
std::process::exit(1);
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -4,28 +4,106 @@ mod translate_body;
|
|||||||
use head_type::*;
|
use head_type::*;
|
||||||
use translate_body::*;
|
use translate_body::*;
|
||||||
|
|
||||||
pub struct ScopedFormula
|
struct ScopedFormula
|
||||||
{
|
{
|
||||||
free_variable_declarations: foliage::VariableDeclarations,
|
free_variable_declarations: foliage::VariableDeclarations,
|
||||||
formula: foliage::Formula,
|
formula: foliage::Formula,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Definitions
|
struct Definitions
|
||||||
{
|
{
|
||||||
head_atom_parameters: std::rc::Rc<foliage::VariableDeclarations>,
|
head_atom_parameters: std::rc::Rc<foliage::VariableDeclarations>,
|
||||||
definitions: Vec<ScopedFormula>,
|
definitions: Vec<ScopedFormula>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn read(rule: &clingo::ast::Rule) -> Result<(), crate::Error>
|
struct Context
|
||||||
|
{
|
||||||
|
pub function_declarations: foliage::FunctionDeclarations,
|
||||||
|
pub predicate_declarations: foliage::PredicateDeclarations,
|
||||||
|
pub variable_declaration_stack: foliage::VariableDeclarationStack,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Context
|
||||||
|
{
|
||||||
|
fn new() -> Self
|
||||||
|
{
|
||||||
|
Self
|
||||||
|
{
|
||||||
|
function_declarations: foliage::FunctionDeclarations::new(),
|
||||||
|
predicate_declarations: foliage::PredicateDeclarations::new(),
|
||||||
|
variable_declaration_stack: foliage::VariableDeclarationStack::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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) =>
|
||||||
|
{
|
||||||
|
if let Err(error) = read_rule(rule, &mut self.context)
|
||||||
|
{
|
||||||
|
log::error!("could not translate input program: {}", error);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
_ => log::debug!("read statement (other kind)"),
|
||||||
|
}
|
||||||
|
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Logger;
|
||||||
|
|
||||||
|
impl clingo::Logger for Logger
|
||||||
|
{
|
||||||
|
fn log(&mut self, code: clingo::Warning, message: &str)
|
||||||
|
{
|
||||||
|
log::warn!("clingo warning ({:?}): {}", code, message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn translate(program: &str) -> i32
|
||||||
|
{
|
||||||
|
let mut statement_handler = StatementHandler::new();
|
||||||
|
|
||||||
|
match clingo::parse_program_with_logger(&program, &mut statement_handler, &mut Logger, std::u32::MAX)
|
||||||
|
{
|
||||||
|
Ok(()) => 0,
|
||||||
|
Err(error) =>
|
||||||
|
{
|
||||||
|
log::error!("could not translate input program: {}", error);
|
||||||
|
1
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn read_rule(rule: &clingo::ast::Rule, context: &mut Context) -> Result<(), crate::Error>
|
||||||
{
|
{
|
||||||
use super::common::FindOrCreatePredicateDeclaration;
|
use super::common::FindOrCreatePredicateDeclaration;
|
||||||
|
|
||||||
let mut function_declarations = foliage::FunctionDeclarations::new();
|
|
||||||
let mut predicate_declarations = foliage::PredicateDeclarations::new();
|
|
||||||
let mut variable_declaration_stack = foliage::VariableDeclarationStack::new();
|
|
||||||
|
|
||||||
let head_type = determine_head_type(rule.head(),
|
let head_type = determine_head_type(rule.head(),
|
||||||
|name, arity| predicate_declarations.find_or_create(name, arity))?;
|
|name, arity| context.predicate_declarations.find_or_create(name, arity))?;
|
||||||
|
|
||||||
let mut definitions
|
let mut definitions
|
||||||
= std::collections::BTreeMap::<std::rc::Rc<foliage::PredicateDeclaration>, Definitions>::new();
|
= std::collections::BTreeMap::<std::rc::Rc<foliage::PredicateDeclaration>, Definitions>::new();
|
||||||
@ -53,10 +131,12 @@ pub fn read(rule: &clingo::ast::Rule) -> Result<(), crate::Error>
|
|||||||
|
|
||||||
let definitions = definitions.get_mut(&head_atom.predicate_declaration).unwrap();
|
let definitions = definitions.get_mut(&head_atom.predicate_declaration).unwrap();
|
||||||
|
|
||||||
variable_declaration_stack.push(std::rc::Rc::clone(&definitions.head_atom_parameters));
|
context.variable_declaration_stack.push(std::rc::Rc::clone(
|
||||||
|
&definitions.head_atom_parameters));
|
||||||
|
|
||||||
let mut definition_arguments = translate_body(rule.body(), &mut function_declarations,
|
let mut definition_arguments = translate_body(rule.body(),
|
||||||
&mut predicate_declarations, &mut variable_declaration_stack)?;
|
&mut context.function_declarations, &mut context.predicate_declarations,
|
||||||
|
&mut context.variable_declaration_stack)?;
|
||||||
|
|
||||||
assert_eq!(definitions.head_atom_parameters.len(), head_atom.arguments.len());
|
assert_eq!(definitions.head_atom_parameters.len(), head_atom.arguments.len());
|
||||||
|
|
||||||
@ -67,30 +147,35 @@ pub fn read(rule: &clingo::ast::Rule) -> Result<(), crate::Error>
|
|||||||
let head_atom_argument = head_atom_arguments_iterator.next().unwrap();
|
let head_atom_argument = head_atom_arguments_iterator.next().unwrap();
|
||||||
|
|
||||||
let translated_head_term = crate::translate::common::choose_value_in_term(
|
let translated_head_term = crate::translate::common::choose_value_in_term(
|
||||||
head_atom_argument, head_atom_parameter, &mut function_declarations,
|
head_atom_argument, head_atom_parameter, &mut context.function_declarations,
|
||||||
&mut variable_declaration_stack)?;
|
&mut context.variable_declaration_stack)?;
|
||||||
|
|
||||||
definition_arguments.push(Box::new(translated_head_term));
|
definition_arguments.push(Box::new(translated_head_term));
|
||||||
}
|
}
|
||||||
|
|
||||||
variable_declaration_stack.pop();
|
context.variable_declaration_stack.pop();
|
||||||
|
|
||||||
|
let mut free_variable_declarations = vec![];
|
||||||
|
|
||||||
|
std::mem::swap(&mut context.variable_declaration_stack.free_variable_declarations,
|
||||||
|
&mut free_variable_declarations);
|
||||||
|
|
||||||
let definition = foliage::Formula::And(definition_arguments);
|
let definition = foliage::Formula::And(definition_arguments);
|
||||||
|
|
||||||
let definition = ScopedFormula
|
let definition = ScopedFormula
|
||||||
{
|
{
|
||||||
free_variable_declarations: variable_declaration_stack.free_variable_declarations,
|
free_variable_declarations,
|
||||||
formula: definition,
|
formula: definition,
|
||||||
};
|
};
|
||||||
|
|
||||||
log::trace!("translated formula: {:?}", definition.formula);
|
log::trace!("translated rule with single atom in head: {:?}", definition.formula);
|
||||||
|
|
||||||
definitions.definitions.push(definition);
|
definitions.definitions.push(definition);
|
||||||
},
|
},
|
||||||
HeadType::ChoiceWithSingleAtom(_) =>
|
HeadType::ChoiceWithSingleAtom(_) =>
|
||||||
log::debug!("translating choice rule with single atom"),
|
log::debug!("translating choice rule with single atom"),
|
||||||
HeadType::IntegrityConstraint =>
|
HeadType::IntegrityConstraint =>
|
||||||
log::debug!("translating integrity constraint"),
|
log::debug!("translated integrity constraint"),
|
||||||
HeadType::Trivial => log::debug!("skipping trivial rule"),
|
HeadType::Trivial => log::debug!("skipping trivial rule"),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user