Add parser support for output statements

This commit is contained in:
Patrick Lühne 2020-05-12 05:27:51 +02:00
parent 32b18e2b63
commit e42fd92d4b
Signed by: patrick
GPG Key ID: 05F3611E97A70ABF
4 changed files with 71 additions and 0 deletions

View File

@ -1,4 +1,5 @@
input: n -> integer. input: n -> integer.
output: q/1.
axiom: forall N1, N2, N3 (N1 > N2 and N3 > 0 -> N1 * N3 > N2 * N3). axiom: forall N1, N2, N3 (N1 > N2 and N3 > 0 -> N1 * N3 > N2 * N3).
axiom: (p(0) and forall N (N >= 0 and p(N) -> p(N + 1))) -> (forall N p(N)). axiom: (p(0) and forall N (N >= 0 and p(N) -> p(N + 1))) -> (forall N p(N)).

View File

@ -15,6 +15,7 @@ pub enum Kind
MissingStatementTerminator, MissingStatementTerminator,
ParseFormula, ParseFormula,
ExpectedIdentifier, ExpectedIdentifier,
ExpectedPredicateSpecifier,
ParsePredicateDeclaration, ParsePredicateDeclaration,
//ParseConstantDeclaration, //ParseConstantDeclaration,
UnknownProofDirection(String), UnknownProofDirection(String),
@ -116,6 +117,11 @@ impl Error
Self::new(Kind::ExpectedIdentifier) Self::new(Kind::ExpectedIdentifier)
} }
pub(crate) fn new_expected_predicate_specifier() -> Self
{
Self::new(Kind::ExpectedPredicateSpecifier)
}
pub(crate) fn new_parse_predicate_declaration() -> Self pub(crate) fn new_parse_predicate_declaration() -> Self
{ {
Self::new(Kind::ParsePredicateDeclaration) Self::new(Kind::ParsePredicateDeclaration)
@ -187,8 +193,11 @@ impl std::fmt::Debug for Error
Kind::UnmatchedParenthesis => write!(formatter, "unmatched parenthesis"), Kind::UnmatchedParenthesis => write!(formatter, "unmatched parenthesis"),
Kind::ParseFormula => write!(formatter, "could not parse formula"), Kind::ParseFormula => write!(formatter, "could not parse formula"),
Kind::ExpectedIdentifier => write!(formatter, "expected constant or predicate name"), Kind::ExpectedIdentifier => write!(formatter, "expected constant or predicate name"),
Kind::ExpectedPredicateSpecifier =>
write!(formatter, "expected predicate specifier (examples: p/0, q/2)"),
Kind::ParsePredicateDeclaration => write!(formatter, Kind::ParsePredicateDeclaration => write!(formatter,
"could not parse predicate declaration"), "could not parse predicate declaration"),
// TODO: rename to ExpectedStatementTerminator
Kind::MissingStatementTerminator => write!(formatter, Kind::MissingStatementTerminator => write!(formatter,
"statement not terminated with . character"), "statement not terminated with . character"),
Kind::UnknownProofDirection(ref proof_direction) => write!(formatter, Kind::UnknownProofDirection(ref proof_direction) => write!(formatter,

View File

@ -306,6 +306,63 @@ fn input_statement_body<'i>(mut input: &'i str, problem: &crate::Problem)
expect_statement_terminator(input) expect_statement_terminator(input)
} }
fn output_statement_body<'i>(mut input: &'i str, problem: &crate::Problem)
-> Result<&'i str, crate::Error>
{
input = input.trim_start();
let mut input_characters = input.chars();
let remaining_input = match input_characters.next()
{
Some(':') => input_characters.as_str(),
_ => return Err(crate::Error::new_expected_colon()),
};
input = remaining_input;
loop
{
input = input.trim_start();
let (constant_or_predicate_name, remaining_input) =
foliage::parse::tokens::identifier(input)
.ok_or_else(|| crate::Error::new_expected_identifier())?;
input = remaining_input.trim_start();
// Only accept output predicate specifiers
if let (Some(arity), remaining_input) = predicate_arity_specifier(input)?
{
input = remaining_input;
let mut output_predicate_declarations =
problem.output_predicate_declarations.borrow_mut();
use foliage::FindOrCreatePredicateDeclaration as _;
let predicate_declaration =
problem.find_or_create_predicate_declaration(constant_or_predicate_name, arity);
output_predicate_declarations.insert(predicate_declaration);
}
else
{
return Err(crate::Error::new_expected_predicate_specifier());
}
let mut input_characters = input.chars();
match input_characters.next()
{
Some(',') => input = input_characters.as_str(),
_ => break,
}
}
expect_statement_terminator(input)
}
pub(crate) fn parse_specification(mut input: &str, problem: &crate::Problem) pub(crate) fn parse_specification(mut input: &str, problem: &crate::Problem)
-> Result<(), crate::Error> -> Result<(), crate::Error>
{ {
@ -424,6 +481,7 @@ pub(crate) fn parse_specification(mut input: &str, problem: &crate::Problem)
continue; continue;
}, },
"input" => input = input_statement_body(input, problem)?, "input" => input = input_statement_body(input, problem)?,
"output" => input = output_statement_body(input, problem)?,
identifier => return Err(crate::Error::new_unknown_statement(identifier.to_string())), identifier => return Err(crate::Error::new_unknown_statement(identifier.to_string())),
} }
} }

View File

@ -97,6 +97,7 @@ pub struct Problem
pub input_constant_declarations: std::cell::RefCell<foliage::FunctionDeclarations>, pub input_constant_declarations: std::cell::RefCell<foliage::FunctionDeclarations>,
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 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 // TODO: clean up as variable declarations are dropped
variable_declaration_domains: std::cell::RefCell<VariableDeclarationDomains>, variable_declaration_domains: std::cell::RefCell<VariableDeclarationDomains>,
@ -120,6 +121,8 @@ impl Problem
std::cell::RefCell::new(InputConstantDeclarationDomains::new()), std::cell::RefCell::new(InputConstantDeclarationDomains::new()),
input_predicate_declarations: input_predicate_declarations:
std::cell::RefCell::new(foliage::PredicateDeclarations::new()), std::cell::RefCell::new(foliage::PredicateDeclarations::new()),
output_predicate_declarations:
std::cell::RefCell::new(foliage::PredicateDeclarations::new()),
variable_declaration_domains: variable_declaration_domains:
std::cell::RefCell::new(VariableDeclarationDomains::new()), std::cell::RefCell::new(VariableDeclarationDomains::new()),