Start testing formula formatter

This commit is contained in:
Patrick Lühne 2020-04-01 10:53:11 +02:00
parent 600a6a1b4b
commit e4fe047aba
Signed by: patrick
GPG Key ID: 05F3611E97A70ABF
2 changed files with 127 additions and 33 deletions

View File

@ -297,26 +297,112 @@ impl std::fmt::Display for crate::Formula
mod tests mod tests
{ {
use crate::*; use crate::*;
use crate::format::terms::tests::*;
fn format(formula: &ast::Formula) -> String fn format(formula: Box<ast::Formula>) -> String
{ {
format!("{}", formula) format!("{}", formula)
} }
#[test] fn equal(left: Box<Term>, right: Box<Term>) -> Box<Formula>
fn compare()
{ {
let ad = std::rc::Rc::new(FunctionDeclaration::new("a".to_string(), 0)); Box::new(Formula::equal(left, right))
let bd = std::rc::Rc::new(FunctionDeclaration::new("b".to_string(), 0)); }
let a = || Box::new(Term::function(std::rc::Rc::clone(&ad), vec![])); fn false_() -> Box<Formula>
let b = || Box::new(Term::function(std::rc::Rc::clone(&bd), vec![])); {
Box::new(Formula::false_())
}
assert_eq!(format(&Formula::greater(a(), b())), "a > b"); fn greater(left: Box<Term>, right: Box<Term>) -> Box<Formula>
assert_eq!(format(&Formula::less(a(), b())), "a < b"); {
assert_eq!(format(&Formula::less_or_equal(a(), b())), "a <= b"); Box::new(Formula::greater(left, right))
assert_eq!(format(&Formula::greater_or_equal(a(), b())), "a >= b"); }
assert_eq!(format(&Formula::equal(a(), b())), "a = b");
assert_eq!(format(&Formula::not_equal(a(), b())), "a != b"); fn greater_or_equal(left: Box<Term>, right: Box<Term>) -> Box<Formula>
{
Box::new(Formula::greater_or_equal(left, right))
}
fn less(left: Box<Term>, right: Box<Term>) -> Box<Formula>
{
Box::new(Formula::less(left, right))
}
fn less_or_equal(left: Box<Term>, right: Box<Term>) -> Box<Formula>
{
Box::new(Formula::less_or_equal(left, right))
}
fn not_equal(left: Box<Term>, right: Box<Term>) -> Box<Formula>
{
Box::new(Formula::not_equal(left, right))
}
fn predicate(name: &str, arguments: Vec<Box<Term>>) -> Box<Formula>
{
Box::new(Formula::predicate(predicate_declaration(name, arguments.len()), arguments))
}
fn predicate_declaration(name: &str, arity: usize) -> std::rc::Rc<PredicateDeclaration>
{
std::rc::Rc::new(PredicateDeclaration::new(name.to_string(), arity))
}
fn true_() -> Box<Formula>
{
Box::new(Formula::true_())
}
#[test]
fn format_boolean()
{
assert_eq!(format(true_()), "true");
assert_eq!(format(false_()), "false");
}
#[test]
fn format_compare()
{
assert_eq!(format(greater(constant("a"), constant("b"))), "a > b");
assert_eq!(format(less(constant("a"), constant("b"))), "a < b");
assert_eq!(format(less_or_equal(constant("a"), constant("b"))), "a <= b");
assert_eq!(format(greater_or_equal(constant("a"), constant("b"))), "a >= b");
assert_eq!(format(equal(constant("a"), constant("b"))), "a = b");
assert_eq!(format(not_equal(constant("a"), constant("b"))), "a != b");
}
#[test]
fn format_predicate()
{
assert_eq!(format(predicate("p", vec![])), "p");
assert_eq!(format(predicate("predicate", vec![])), "predicate");
assert_eq!(format(predicate("q", vec![constant("a")])), "q(a)");
assert_eq!(format(
predicate("q", vec![constant("a"), constant("b"), constant("c")])),
"q(a, b, c)");
assert_eq!(format(
predicate("predicate", vec![constant("a"), constant("b"), constant("c")])),
"predicate(a, b, c)");
assert_eq!(format(
predicate("predicate", vec![
exponentiate(absolute_value(multiply(constant("a"), integer(-20))), integer(2)),
string("test"),
function("f", vec![multiply(add(constant("b"), constant("c")),
subtract(constant("b"), constant("c"))), infimum(), variable("X")])])),
"predicate(|a * -20| ** 2, \"test\", f((b + c) * (b - c), #inf, X))");
// TODO: escape predicates that start with capital letters or that conflict with keywords
}
#[test]
fn format_predicate_declaration()
{
assert_eq!(format!("{}", predicate_declaration("p", 0)), "p/0");
assert_eq!(format!("{}", predicate_declaration("predicate", 0)), "predicate/0");
assert_eq!(format!("{}", predicate_declaration("q", 1)), "q/1");
assert_eq!(format!("{}", predicate_declaration("q", 3)), "q/3");
assert_eq!(format!("{}", predicate_declaration("predicate", 3)), "predicate/3");
} }
} }

View File

@ -255,7 +255,7 @@ impl std::fmt::Display for crate::Term
} }
#[cfg(test)] #[cfg(test)]
mod tests pub(crate) mod tests
{ {
use crate::*; use crate::*;
@ -264,97 +264,97 @@ mod tests
format!("{}", term) format!("{}", term)
} }
fn absolute_value(argument: Box<Term>) -> Box<Term> pub(crate) fn absolute_value(argument: Box<Term>) -> Box<Term>
{ {
Box::new(Term::absolute_value(argument)) Box::new(Term::absolute_value(argument))
} }
fn add(left: Box<Term>, right: Box<Term>) -> Box<Term> pub(crate) fn add(left: Box<Term>, right: Box<Term>) -> Box<Term>
{ {
Box::new(Term::add(left, right)) Box::new(Term::add(left, right))
} }
fn constant(name: &str) -> Box<Term> pub(crate) fn constant(name: &str) -> Box<Term>
{ {
Box::new(Term::function(function_declaration(name, 0), vec![])) Box::new(Term::function(function_declaration(name, 0), vec![]))
} }
fn divide(left: Box<Term>, right: Box<Term>) -> Box<Term> pub(crate) fn divide(left: Box<Term>, right: Box<Term>) -> Box<Term>
{ {
Box::new(Term::divide(left, right)) Box::new(Term::divide(left, right))
} }
fn exponentiate(left: Box<Term>, right: Box<Term>) -> Box<Term> pub(crate) fn exponentiate(left: Box<Term>, right: Box<Term>) -> Box<Term>
{ {
Box::new(Term::exponentiate(left, right)) Box::new(Term::exponentiate(left, right))
} }
fn false_() -> Box<Term> pub(crate) fn false_() -> Box<Term>
{ {
Box::new(Term::false_()) Box::new(Term::false_())
} }
fn function(name: &str, arguments: Vec<Box<Term>>) -> Box<Term> pub(crate) fn function(name: &str, arguments: Vec<Box<Term>>) -> Box<Term>
{ {
Box::new(Term::function(function_declaration(name, arguments.len()), arguments)) Box::new(Term::function(function_declaration(name, arguments.len()), arguments))
} }
fn function_declaration(name: &str, arity: usize) -> std::rc::Rc<FunctionDeclaration> pub(crate) fn function_declaration(name: &str, arity: usize) -> std::rc::Rc<FunctionDeclaration>
{ {
std::rc::Rc::new(FunctionDeclaration::new(name.to_string(), arity)) std::rc::Rc::new(FunctionDeclaration::new(name.to_string(), arity))
} }
fn infimum() -> Box<Term> pub(crate) fn infimum() -> Box<Term>
{ {
Box::new(Term::infimum()) Box::new(Term::infimum())
} }
fn integer(value: i32) -> Box<Term> pub(crate) fn integer(value: i32) -> Box<Term>
{ {
Box::new(Term::integer(value)) Box::new(Term::integer(value))
} }
fn modulo(left: Box<Term>, right: Box<Term>) -> Box<Term> pub(crate) fn modulo(left: Box<Term>, right: Box<Term>) -> Box<Term>
{ {
Box::new(Term::modulo(left, right)) Box::new(Term::modulo(left, right))
} }
fn multiply(left: Box<Term>, right: Box<Term>) -> Box<Term> pub(crate) fn multiply(left: Box<Term>, right: Box<Term>) -> Box<Term>
{ {
Box::new(Term::multiply(left, right)) Box::new(Term::multiply(left, right))
} }
fn negative(argument: Box<Term>) -> Box<Term> pub(crate) fn negative(argument: Box<Term>) -> Box<Term>
{ {
Box::new(Term::negative(argument)) Box::new(Term::negative(argument))
} }
fn subtract(left: Box<Term>, right: Box<Term>) -> Box<Term> pub(crate) fn subtract(left: Box<Term>, right: Box<Term>) -> Box<Term>
{ {
Box::new(Term::subtract(left, right)) Box::new(Term::subtract(left, right))
} }
fn supremum() -> Box<Term> pub(crate) fn supremum() -> Box<Term>
{ {
Box::new(Term::supremum()) Box::new(Term::supremum())
} }
fn string(value: &str) -> Box<Term> pub(crate) fn string(value: &str) -> Box<Term>
{ {
Box::new(Term::string(value.to_string())) Box::new(Term::string(value.to_string()))
} }
fn true_() -> Box<Term> pub(crate) fn true_() -> Box<Term>
{ {
Box::new(Term::true_()) Box::new(Term::true_())
} }
fn variable(name: &str) -> Box<Term> pub(crate) fn variable(name: &str) -> Box<Term>
{ {
Box::new(Term::variable(variable_declaration(name))) Box::new(Term::variable(variable_declaration(name)))
} }
fn variable_declaration(name: &str) -> std::rc::Rc<VariableDeclaration> pub(crate) fn variable_declaration(name: &str) -> std::rc::Rc<VariableDeclaration>
{ {
std::rc::Rc::new(VariableDeclaration::new(name.to_string())) std::rc::Rc::new(VariableDeclaration::new(name.to_string()))
} }
@ -422,6 +422,14 @@ mod tests
function("function", vec![constant("a"), constant("b"), constant("c")])), function("function", vec![constant("a"), constant("b"), constant("c")])),
"function(a, b, c)"); "function(a, b, c)");
assert_eq!(format(
function("function", vec![
exponentiate(absolute_value(multiply(constant("a"), integer(-20))), integer(2)),
string("test"),
function("f", vec![multiply(add(constant("b"), constant("c")),
subtract(constant("b"), constant("c"))), infimum(), variable("X")])])),
"function(|a * -20| ** 2, \"test\", f((b + c) * (b - c), #inf, X))");
// TODO: escape functions that start with capital letters or that conflict with keywords // TODO: escape functions that start with capital letters or that conflict with keywords
} }