Add parser support for output statements
This commit is contained in:
parent
32b18e2b63
commit
e42fd92d4b
@ -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)).
|
||||||
|
@ -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,
|
||||||
|
@ -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())),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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()),
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user