diff --git a/src/format/formulas.rs b/src/format/formulas.rs index b734875..010665f 100644 --- a/src/format/formulas.rs +++ b/src/format/formulas.rs @@ -490,7 +490,7 @@ mod tests Box::new(Formula::or(arguments)) } - fn predicate(name: &str, arguments: Vec>) -> Box + fn predicate(name: &str, arguments: Terms) -> Box { Box::new(Formula::predicate(predicate_declaration(name, arguments.len()), arguments)) } @@ -658,8 +658,8 @@ mod tests assert!(predicate("predicate", vec![ exponentiate(absolute_value(multiply(a(), integer(-20))), integer(2)), string("test"), - function("f", vec![multiply(add(b(), c()), - subtract(b(), c())), infimum(), variable("X")])]), + function("f", vec![multiply(add(b(), c()), subtract(b(), 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 diff --git a/src/format/terms.rs b/src/format/terms.rs index 4f27aa7..e1a3cdc 100644 --- a/src/format/terms.rs +++ b/src/format/terms.rs @@ -397,15 +397,45 @@ pub(crate) mod tests vec![a(), b(), c()] } + pub(crate) fn a1b1c1() -> Terms + { + vec![constant("a1"), constant("b1"), constant("c1")] + } + + pub(crate) fn a2b2c2() -> Terms + { + vec![constant("a2"), constant("b2"), constant("c2")] + } + + pub(crate) fn x() -> Box + { + variable("X") + } + + pub(crate) fn y() -> Box + { + variable("Y") + } + + pub(crate) fn z() -> Box + { + variable("Z") + } + + pub(crate) fn xyz() -> Terms + { + vec![x(), y(), z()] + } + #[test] fn format_binary_operation() { - assert!(add(constant("a"), constant("b")), "a + b"); - assert!(subtract(constant("a"), constant("b")), "a - b"); - assert!(multiply(constant("a"), constant("b")), "a * b"); - assert!(divide(constant("a"), constant("b")), "a / b"); - assert!(modulo(constant("a"), constant("b")), "a % b"); - assert!(exponentiate(constant("a"), constant("b")), "a ** b"); + assert!(add(a(), constant("b")), "a + b"); + assert!(subtract(a(), constant("b")), "a - b"); + assert!(multiply(a(), constant("b")), "a * b"); + assert!(divide(a(), constant("b")), "a / b"); + assert!(modulo(a(), constant("b")), "a % b"); + assert!(exponentiate(a(), constant("b")), "a ** b"); } #[test] @@ -450,18 +480,16 @@ pub(crate) mod tests #[test] fn format_function() { - assert!(constant("a"), "a"); + assert!(a(), "a"); assert!(constant("constant"), "constant"); - assert!(function("f", vec![constant("a")]), "f(a)"); - assert!(function("f", vec![constant("a"), constant("b"), constant("c")]), "f(a, b, c)"); - assert!(function("function", vec![constant("a"), constant("b"), constant("c")]), - "function(a, b, c)"); + assert!(function("f", vec![a()]), "f(a)"); + assert!(function("f", abc()), "f(a, b, c)"); + assert!(function("function", abc()), "function(a, b, c)"); assert!(function("function", vec![ - exponentiate(absolute_value(multiply(constant("a"), integer(-20))), integer(2)), + exponentiate(absolute_value(multiply(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("f", vec![multiply(add(b(), c()), subtract(b(), c())), infimum(), 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 @@ -485,153 +513,199 @@ pub(crate) mod tests } #[test] - fn format_combination_boolean_and_lower() + fn format_combinations_boolean() { + // Function + Boolean + assert!(function("f", vec![true_()]), "f(true)"); + assert!(function("f", vec![false_()]), "f(false)"); assert!(function("f", vec![true_(), true_(), true_()]), "f(true, true, true)"); assert!(function("f", vec![false_(), false_(), false_()]), "f(false, false, false)"); + // Absolute value + Boolean assert!(absolute_value(true_()), "|true|"); assert!(absolute_value(false_()), "|false|"); + // Negative + Boolean assert!(negative(true_()), "-true"); assert!(negative(false_()), "-false"); + // Exponentiate + Boolean assert!(exponentiate(true_(), true_()), "true ** true"); assert!(exponentiate(false_(), false_()), "false ** false"); + // Multiply + Boolean assert!(multiply(true_(), true_()), "true * true"); assert!(multiply(false_(), false_()), "false * false"); + // Divide + Boolean assert!(divide(true_(), true_()), "true / true"); assert!(divide(false_(), false_()), "false / false"); + // Modulo + Boolean assert!(modulo(true_(), true_()), "true % true"); assert!(modulo(false_(), false_()), "false % false"); + // Add + Boolean assert!(add(true_(), true_()), "true + true"); assert!(add(false_(), false_()), "false + false"); + // Subtract + Boolean assert!(subtract(true_(), true_()), "true - true"); assert!(subtract(false_(), false_()), "false - false"); } #[test] - fn format_combination_special_integer_and_lower() + fn format_combinations_special_integer() { + // Function + special integer + assert!(function("f", vec![infimum()]), "f(#inf)"); + assert!(function("f", vec![supremum()]), "f(#sup)"); assert!(function("f", vec![infimum(), infimum(), infimum()]), "f(#inf, #inf, #inf)"); assert!(function("f", vec![supremum(), supremum(), supremum()]), "f(#sup, #sup, #sup)"); + // Absolute value + special integer assert!(absolute_value(infimum()), "|#inf|"); assert!(absolute_value(supremum()), "|#sup|"); + // Negative + special integer assert!(negative(infimum()), "-#inf"); assert!(negative(supremum()), "-#sup"); + // Exponentiate + special integer assert!(exponentiate(infimum(), infimum()), "#inf ** #inf"); assert!(exponentiate(supremum(), supremum()), "#sup ** #sup"); + // Multiply + special integer assert!(multiply(infimum(), infimum()), "#inf * #inf"); assert!(multiply(supremum(), supremum()), "#sup * #sup"); + // Divide + special integer assert!(divide(infimum(), infimum()), "#inf / #inf"); assert!(divide(supremum(), supremum()), "#sup / #sup"); + // Modulo + special integer assert!(modulo(infimum(), infimum()), "#inf % #inf"); assert!(modulo(supremum(), supremum()), "#sup % #sup"); + // Add + special integer assert!(add(infimum(), infimum()), "#inf + #inf"); assert!(add(supremum(), supremum()), "#sup + #sup"); + // Subtract + special integer assert!(subtract(infimum(), infimum()), "#inf - #inf"); assert!(subtract(supremum(), supremum()), "#sup - #sup"); } #[test] - fn format_combination_integer_and_lower() + fn format_combinations_integer() { + // Function + integer + assert!(function("f", vec![integer(0)]), "f(0)"); + assert!(function("f", vec![integer(10000)]), "f(10000)"); + assert!(function("f", vec![integer(-10000)]), "f(-10000)"); assert!(function("f", vec![integer(0), integer(0), integer(0)]), "f(0, 0, 0)"); assert!(function("f", vec![integer(10000), integer(10000), integer(10000)]), "f(10000, 10000, 10000)"); assert!(function("f", vec![integer(-10000), integer(-10000), integer(-10000)]), "f(-10000, -10000, -10000)"); + // Absolute value + integer assert!(absolute_value(integer(0)), "|0|"); assert!(absolute_value(integer(10000)), "|10000|"); assert!(absolute_value(integer(-10000)), "|-10000|"); + // Negative + integer assert!(negative(integer(0)), "-0"); assert!(negative(integer(10000)), "-10000"); assert!(negative(integer(-10000)), "--10000"); + // Exponentiate + integer assert!(exponentiate(integer(0), integer(0)), "0 ** 0"); assert!(exponentiate(integer(10000), integer(10000)), "10000 ** 10000"); assert!(exponentiate(integer(-10000), integer(-10000)), "-10000 ** -10000"); + // Multiply + integer assert!(multiply(integer(0), integer(0)), "0 * 0"); assert!(multiply(integer(10000), integer(10000)), "10000 * 10000"); assert!(multiply(integer(-10000), integer(-10000)), "-10000 * -10000"); + // Divide + integer assert!(divide(integer(0), integer(0)), "0 / 0"); assert!(divide(integer(10000), integer(10000)), "10000 / 10000"); assert!(divide(integer(-10000), integer(-10000)), "-10000 / -10000"); + // Modulo + integer assert!(modulo(integer(0), integer(0)), "0 % 0"); assert!(modulo(integer(10000), integer(10000)), "10000 % 10000"); assert!(modulo(integer(-10000), integer(-10000)), "-10000 % -10000"); + // Add + integer assert!(add(integer(0), integer(0)), "0 + 0"); assert!(add(integer(10000), integer(10000)), "10000 + 10000"); assert!(add(integer(-10000), integer(-10000)), "-10000 + -10000"); + // Subtract + integer assert!(subtract(integer(0), integer(0)), "0 - 0"); assert!(subtract(integer(10000), integer(10000)), "10000 - 10000"); assert!(subtract(integer(-10000), integer(-10000)), "-10000 - -10000"); } #[test] - fn format_combination_string_and_lower() + fn format_combinations_string() { + // Function + string + assert!(function("f", vec![string("")]), "f(\"\")"); + assert!(function("f", vec![string("test 123")]), "f(\"test 123\")"); + assert!(function("f", vec![string("\\a\nb🙂c\t")]), "f(\"\\\\a\\nb🙂c\\t\")"); assert!(function("f", vec![string(""), string(""), string("")]), "f(\"\", \"\", \"\")"); assert!(function("f", vec![string("test 123"), string("test 123"), string("test 123")]), "f(\"test 123\", \"test 123\", \"test 123\")"); assert!(function("f", vec![string("\\a\nb🙂c\t"), string("\\a\nb🙂c\t"), - string("\\a\nb🙂c\t")]), + string("\\a\nb🙂c\t")]), "f(\"\\\\a\\nb🙂c\\t\", \"\\\\a\\nb🙂c\\t\", \"\\\\a\\nb🙂c\\t\")"); + // Absolute value + string assert!(absolute_value(string("")), "|\"\"|"); assert!(absolute_value(string("test 123")), "|\"test 123\"|"); assert!(absolute_value(string("\\a\nb🙂c\t")), "|\"\\\\a\\nb🙂c\\t\"|"); + // Negative + string assert!(negative(string("")), "-\"\""); assert!(negative(string("test 123")), "-\"test 123\""); assert!(negative(string("\\a\nb🙂c\t")), "-\"\\\\a\\nb🙂c\\t\""); + // Exponentiate + string assert!(exponentiate(string(""), string("")), "\"\" ** \"\""); assert!(exponentiate(string("test 123"), string("test 123")), "\"test 123\" ** \"test 123\""); assert!(exponentiate(string("\\a\nb🙂c\t"), string("\\a\nb🙂c\t")), "\"\\\\a\\nb🙂c\\t\" ** \"\\\\a\\nb🙂c\\t\""); + // Multiply + string assert!(multiply(string(""), string("")), "\"\" * \"\""); assert!(multiply(string("test 123"), string("test 123")), "\"test 123\" * \"test 123\""); assert!(multiply(string("\\a\nb🙂c\t"), string("\\a\nb🙂c\t")), "\"\\\\a\\nb🙂c\\t\" * \"\\\\a\\nb🙂c\\t\""); + // Divide + string assert!(divide(string(""), string("")), "\"\" / \"\""); assert!(divide(string("test 123"), string("test 123")), "\"test 123\" / \"test 123\""); assert!(divide(string("\\a\nb🙂c\t"), string("\\a\nb🙂c\t")), "\"\\\\a\\nb🙂c\\t\" / \"\\\\a\\nb🙂c\\t\""); + // Modulo + string assert!(modulo(string(""), string("")), "\"\" % \"\""); assert!(modulo(string("test 123"), string("test 123")), "\"test 123\" % \"test 123\""); assert!(modulo(string("\\a\nb🙂c\t"), string("\\a\nb🙂c\t")), "\"\\\\a\\nb🙂c\\t\" % \"\\\\a\\nb🙂c\\t\""); + // Add + string assert!(add(string(""), string("")), "\"\" + \"\""); assert!(add(string("test 123"), string("test 123")), "\"test 123\" + \"test 123\""); assert!(add(string("\\a\nb🙂c\t"), string("\\a\nb🙂c\t")), "\"\\\\a\\nb🙂c\\t\" + \"\\\\a\\nb🙂c\\t\""); + // Subtract + string assert!(subtract(string(""), string("")), "\"\" - \"\""); assert!(subtract(string("test 123"), string("test 123")), "\"test 123\" - \"test 123\""); assert!(subtract(string("\\a\nb🙂c\t"), string("\\a\nb🙂c\t")), @@ -639,266 +713,364 @@ pub(crate) mod tests } #[test] - fn format_combination_variable_and_lower() + fn format_combinations_variable() { - assert!(variable("X"), "X"); - assert!(variable("Variable"), "Variable"); + let variable = || variable("Variable"); - assert!(absolute_value(variable("X")), "|X|"); - assert!(absolute_value(variable("Variable")), "|Variable|"); + // Function + variable + assert!(function("f", vec![x()]), "f(X)"); + assert!(function("f", vec![variable()]), "f(Variable)"); + assert!(function("f", xyz()), "f(X, Y, Z)"); + assert!(function("f", vec![variable(), variable(), variable()]), + "f(Variable, Variable, Variable)"); - assert!(negative(variable("X")), "-X"); - assert!(negative(variable("Variable")), "-Variable"); + // Absolute value + variable + assert!(absolute_value(x()), "|X|"); + assert!(absolute_value(variable()), "|Variable|"); - assert!(exponentiate(variable("X"), variable("X")), "X ** X"); - assert!(exponentiate(variable("Variable"), variable("Variable")), "Variable ** Variable"); + // Negative + variable + assert!(negative(x()), "-X"); + assert!(negative(variable()), "-Variable"); - assert!(multiply(variable("X"), variable("X")), "X * X"); - assert!(multiply(variable("Variable"), variable("Variable")), "Variable * Variable"); + // Exponentiate + variable + assert!(exponentiate(x(), y()), "X ** Y"); + assert!(exponentiate(variable(), variable()), "Variable ** Variable"); - assert!(divide(variable("X"), variable("X")), "X / X"); - assert!(divide(variable("Variable"), variable("Variable")), "Variable / Variable"); + // Multiply + variable + assert!(multiply(x(), y()), "X * Y"); + assert!(multiply(variable(), variable()), "Variable * Variable"); - assert!(modulo(variable("X"), variable("X")), "X % X"); - assert!(modulo(variable("Variable"), variable("Variable")), "Variable % Variable"); + // Divide + variable + assert!(divide(x(), y()), "X / Y"); + assert!(divide(variable(), variable()), "Variable / Variable"); - assert!(add(variable("X"), variable("X")), "X + X"); - assert!(add(variable("Variable"), variable("Variable")), "Variable + Variable"); + // Modulo + variable + assert!(modulo(x(), y()), "X % Y"); + assert!(modulo(variable(), variable()), "Variable % Variable"); - assert!(subtract(variable("X"), variable("X")), "X - X"); - assert!(subtract(variable("Variable"), variable("Variable")), "Variable - Variable"); + // Add + variable + assert!(add(x(), y()), "X + Y"); + assert!(add(variable(), variable()), "Variable + Variable"); + + // Subtract + variable + assert!(subtract(x(), y()), "X - Y"); + assert!(subtract(variable(), variable()), "Variable - Variable"); } #[test] - fn format_combination_function_and_lower() + fn format_combinations_function() { - let f1 = || constant("a"); - let f2 = || constant("constant"); - let f3 = || function("f", vec![constant("a")]); - let f4 = || function("function", vec![constant("a"), constant("b"), constant("c")]); + let f_a = || function("f", vec![a()]); + let g_b = || function("g", vec![b()]); + let f_abc = || function("f", abc()); + let f_a1b1c1 = || function("f", a1b1c1()); + let g_a2b2c2 = || function("g", a2b2c2()); - assert!(absolute_value(f1()), "|a|"); - assert!(absolute_value(f2()), "|constant|"); - assert!(absolute_value(f3()), "|f(a)|"); - assert!(absolute_value(f4()), "|function(a, b, c)|"); - assert!(function("f", vec![absolute_value(constant("a"))]), "f(|a|)"); - assert!(function("f", vec![absolute_value(constant("a")), absolute_value(constant("b")), - absolute_value(constant("c"))]), + // Function + function + // TODO + + // Absolute value + function + assert!(absolute_value(a()), "|a|"); + assert!(absolute_value(f_a()), "|f(a)|"); + assert!(absolute_value(f_abc()), "|f(a, b, c)|"); + + // Negative + function + assert!(negative(a()), "-a"); + assert!(negative(f_a()), "-f(a)"); + assert!(negative(f_abc()), "-f(a, b, c)"); + + // Exponentiate + function + assert!(exponentiate(a(), b()), "a ** b"); + assert!(exponentiate(f_a(), g_b()), "f(a) ** g(b)"); + assert!(exponentiate(f_a1b1c1(), g_a2b2c2()), "f(a1, b1, c1) ** g(a2, b2, c2)"); + + // Multiply + function + assert!(multiply(a(), b()), "a * b"); + assert!(multiply(f_a(), g_b()), "f(a) * g(b)"); + assert!(multiply(f_a1b1c1(), g_a2b2c2()), "f(a1, b1, c1) * g(a2, b2, c2)"); + + // Divide + function + assert!(divide(a(), b()), "a / b"); + assert!(divide(f_a(), g_b()), "f(a) / g(b)"); + assert!(divide(f_a1b1c1(), g_a2b2c2()), "f(a1, b1, c1) / g(a2, b2, c2)"); + + // Modulo + function + assert!(modulo(a(), b()), "a % b"); + assert!(modulo(f_a(), g_b()), "f(a) % g(b)"); + assert!(modulo(f_a1b1c1(), g_a2b2c2()), "f(a1, b1, c1) % g(a2, b2, c2)"); + + // Add + function + assert!(add(a(), b()), "a + b"); + assert!(add(f_a(), g_b()), "f(a) + g(b)"); + assert!(add(f_a1b1c1(), g_a2b2c2()), "f(a1, b1, c1) + g(a2, b2, c2)"); + + // Subtract + function + assert!(subtract(a(), b()), "a - b"); + assert!(subtract(f_a(), g_b()), "f(a) - g(b)"); + assert!(subtract(f_a1b1c1(), g_a2b2c2()), "f(a1, b1, c1) - g(a2, b2, c2)"); + } + + #[test] + fn format_combinations_absolute_value() + { + // Function + absolute value + assert!(function("f", vec![absolute_value(a())]), "f(|a|)"); + assert!(function("f", vec![absolute_value(a()), absolute_value(b()), absolute_value(c())]), "f(|a|, |b|, |c|)"); - assert!(negative(f1()), "-a"); - assert!(negative(f2()), "-constant"); - assert!(negative(f3()), "-f(a)"); - assert!(negative(f4()), "-function(a, b, c)"); - assert!(function("f", vec![negative(constant("a"))]), "f(-a)"); - assert!(function("f", vec![negative(constant("a")), negative(constant("b")), - negative(constant("c"))]), - "f(-a, -b, -c)"); + // Absolute value + absolute value + assert!(absolute_value(absolute_value(a())), "||a||"); - assert!(exponentiate(f1(), f1()), "a ** a"); - assert!(exponentiate(f2(), f2()), "constant ** constant"); - assert!(exponentiate(f3(), f3()), "f(a) ** f(a)"); - assert!(exponentiate(f4(), f4()), "function(a, b, c) ** function(a, b, c)"); - assert!(function("f", vec![exponentiate(constant("a"), constant("b"))]), "f(a ** b)"); - assert!(function("f", vec![exponentiate(constant("a"), constant("b")), - exponentiate(constant("c"), constant("d")), - exponentiate(constant("e"), constant("f"))]), - "f(a ** b, c ** d, e ** f)"); + // Negative + absolute value + assert!(negative(absolute_value(a())), "-|a|"); - assert!(multiply(f1(), f1()), "a * a"); - assert!(multiply(f2(), f2()), "constant * constant"); - assert!(multiply(f3(), f3()), "f(a) * f(a)"); - assert!(multiply(f4(), f4()), "function(a, b, c) * function(a, b, c)"); - assert!(function("f", vec![multiply(constant("a"), constant("b"))]), "f(a * b)"); - assert!(function("f", vec![multiply(constant("a"), constant("b")), - multiply(constant("c"), constant("d")), multiply(constant("e"), constant("f"))]), - "f(a * b, c * d, e * f)"); + // Exponentiate + absolute value + assert!(exponentiate(absolute_value(a()), absolute_value(b())), "|a| ** |b|"); - assert!(divide(f1(), f1()), "a / a"); - assert!(divide(f2(), f2()), "constant / constant"); - assert!(divide(f3(), f3()), "f(a) / f(a)"); - assert!(divide(f4(), f4()), "function(a, b, c) / function(a, b, c)"); - assert!(function("f", vec![divide(constant("a"), constant("b"))]), "f(a / b)"); - assert!(function("f", vec![divide(constant("a"), constant("b")), - divide(constant("c"), constant("d")), divide(constant("e"), constant("f"))]), - "f(a / b, c / d, e / f)"); + // Multiply + absolute value + assert!(multiply(absolute_value(a()), absolute_value(b())), "|a| * |b|"); - assert!(modulo(f1(), f1()), "a % a"); - assert!(modulo(f2(), f2()), "constant % constant"); - assert!(modulo(f3(), f3()), "f(a) % f(a)"); - assert!(modulo(f4(), f4()), "function(a, b, c) % function(a, b, c)"); - assert!(function("f", vec![modulo(constant("a"), constant("b"))]), "f(a % b)"); - assert!(function("f", vec![modulo(constant("a"), constant("b")), - modulo(constant("c"), constant("d")), modulo(constant("e"), constant("f"))]), - "f(a % b, c % d, e % f)"); + // Divide + absolute value + assert!(divide(absolute_value(a()), absolute_value(b())), "|a| / |b|"); - assert!(add(f1(), f1()), "a + a"); - assert!(add(f2(), f2()), "constant + constant"); - assert!(add(f3(), f3()), "f(a) + f(a)"); - assert!(add(f4(), f4()), "function(a, b, c) + function(a, b, c)"); - assert!(function("f", vec![add(constant("a"), constant("b"))]), "f(a + b)"); - assert!(function("f", vec![add(constant("a"), constant("b")), - add(constant("c"), constant("d")), add(constant("e"), constant("f"))]), - "f(a + b, c + d, e + f)"); + // Modulo + absolute value + assert!(modulo(absolute_value(a()), absolute_value(b())), "|a| % |b|"); - assert!(subtract(f1(), f1()), "a - a"); - assert!(subtract(f2(), f2()), "constant - constant"); - assert!(subtract(f3(), f3()), "f(a) - f(a)"); - assert!(subtract(f4(), f4()), "function(a, b, c) - function(a, b, c)"); - assert!(function("f", vec![subtract(constant("a"), constant("b"))]), "f(a - b)"); - assert!(function("f", vec![subtract(constant("a"), constant("b")), - subtract(constant("c"), constant("d")), subtract(constant("e"), constant("f"))]), - "f(a - b, c - d, e - f)"); + // Add + absolute value + assert!(add(absolute_value(a()), absolute_value(b())), "|a| + |b|"); + + // Subtract + absolute value + assert!(subtract(absolute_value(a()), absolute_value(b())), "|a| - |b|"); } #[test] - fn format_combination_absolute_value_and_lower() + fn format_combinations_negative() { - assert!(absolute_value(absolute_value(constant("a"))), "||a||"); - assert!(absolute_value(negative(constant("a"))), "|-a|"); - assert!(negative(absolute_value(constant("a"))), "-|a|"); - assert!(absolute_value(add(constant("a"), constant("b"))), "|a + b|"); - assert!(add(absolute_value(constant("a")), absolute_value(constant("b"))), "|a| + |b|"); - assert!(absolute_value(subtract(constant("a"), constant("b"))), "|a - b|"); - assert!(subtract(absolute_value(constant("a")), absolute_value(constant("b"))), - "|a| - |b|"); - assert!(absolute_value(multiply(constant("a"), constant("b"))), "|a * b|"); - assert!(multiply(absolute_value(constant("a")), absolute_value(constant("b"))), - "|a| * |b|"); - assert!(absolute_value(divide(constant("a"), constant("b"))), "|a / b|"); - assert!( - divide(absolute_value(constant("a")), absolute_value(constant("b"))), "|a| / |b|"); - assert!(absolute_value(modulo(constant("a"), constant("b"))), "|a % b|"); - assert!(modulo(absolute_value(constant("a")), absolute_value(constant("b"))), "|a| % |b|"); - assert!(absolute_value(exponentiate(constant("a"), constant("b"))), "|a ** b|"); - assert!(exponentiate(absolute_value(constant("a")), absolute_value(constant("b"))), - "|a| ** |b|"); + // Function + negative + assert!(function("f", vec![negative(a())]), "f(-a)"); + assert!(function("f", vec![negative(a()), negative(b()), negative(c())]), "f(-a, -b, -c)"); + + // Absolute value + negative + assert!(absolute_value(negative(a())), "|-a|"); + + // Negative + negative + assert!(negative(negative(a())), "--a"); + + // Exponentiate + negative + assert!(exponentiate(negative(a()), negative(b())), "-a ** -b"); + + // Multiply + negative + assert!(multiply(negative(a()), negative(b())), "-a * -b"); + + // Divide + negative + assert!(divide(negative(a()), negative(b())), "-a / -b"); + + // Modulo + negative + assert!(modulo(negative(a()), negative(b())), "-a % -b"); + + // Add + negative + assert!(add(negative(a()), negative(b())), "-a + -b"); + + // Subtract + negative + assert!(subtract(negative(a()), negative(b())), "-a - -b"); } #[test] - fn format_combination_negative_and_lower() + fn format_combinations_exponentiate() { - assert!(negative(negative(constant("a"))), "--a"); - assert!(add(negative(constant("a")), negative(constant("b"))), "-a + -b"); - assert!(negative(add(constant("a"), constant("b"))), "-(a + b)"); - assert!(subtract(negative(constant("a")), negative(constant("b"))), "-a - -b"); - assert!(negative(subtract(constant("a"), constant("b"))), "-(a - b)"); - assert!(multiply(negative(constant("a")), negative(constant("b"))), "-a * -b"); - assert!(negative(multiply(constant("a"), constant("b"))), "-(a * b)"); - assert!(divide(negative(constant("a")), negative(constant("b"))), "-a / -b"); - assert!(negative(divide(constant("a"), constant("b"))), "-(a / b)"); - assert!(modulo(negative(constant("a")), negative(constant("b"))), "-a % -b"); - assert!(negative(modulo(constant("a"), constant("b"))), "-(a % b)"); - assert!(exponentiate(negative(constant("a")), negative(constant("b"))), "-a ** -b"); - assert!(negative(exponentiate(constant("a"), constant("b"))), "-(a ** b)"); + // Function + exponentiate + assert!(function("f", vec![exponentiate(a(), b())]), "f(a ** b)"); + assert!(function("f", vec![exponentiate(a(), b()), exponentiate(c(), d()), + exponentiate(e(), a())]), + "f(a ** b, c ** d, e ** a)"); + + // Absolute value + exponentiate + assert!(absolute_value(exponentiate(a(), b())), "|a ** b|"); + + // Negative + exponentiate + assert!(negative(exponentiate(a(), b())), "-(a ** b)"); + + // Exponentiate + exponentiate + assert!(exponentiate(exponentiate(a(), b()), exponentiate(c(), d())), "(a ** b) ** c ** d"); + + // Multiply + exponentiate + assert!(multiply(exponentiate(a(), b()), exponentiate(c(), d())), "a ** b * c ** d"); + + // Divide + exponentiate + assert!(divide(exponentiate(a(), b()), exponentiate(c(), d())), "a ** b / c ** d"); + + // Modulo + exponentiate + assert!(modulo(exponentiate(a(), b()), exponentiate(c(), d())), "a ** b % c ** d"); + + // Add + exponentiate + assert!(add(exponentiate(a(), b()), exponentiate(c(), d())), "a ** b + c ** d"); + + // Subtract + exponentiate + assert!(subtract(exponentiate(a(), b()), exponentiate(c(), d())), "a ** b - c ** d"); } #[test] - fn format_combination_exponentiate_and_lower() + fn format_combinations_multiply() { - assert!(exponentiate(exponentiate(constant("a"), constant("b")), - exponentiate(constant("c"), constant("d"))), - "(a ** b) ** c ** d"); - assert!(exponentiate(multiply(constant("a"), constant("b")), - multiply(constant("c"), constant("d"))), - "(a * b) ** (c * d)"); - assert!(multiply(exponentiate(constant("a"), constant("b")), - exponentiate(constant("c"), constant("d"))), - "a ** b * c ** d"); - assert!(exponentiate(divide(constant("a"), constant("b")), - divide(constant("c"), constant("d"))), - "(a / b) ** (c / d)"); - assert!(divide(exponentiate(constant("a"), constant("b")), - exponentiate(constant("c"), constant("d"))), - "a ** b / c ** d"); - assert!(exponentiate(modulo(constant("a"), constant("b")), - modulo(constant("c"), constant("d"))), - "(a % b) ** (c % d)"); - assert!(modulo(exponentiate(constant("a"), constant("b")), - exponentiate(constant("c"), constant("d"))), - "a ** b % c ** d"); - assert!(exponentiate(add(constant("a"), constant("b")), add(constant("c"), constant("d"))), - "(a + b) ** (c + d)"); - assert!(add(exponentiate(constant("a"), constant("b")), - exponentiate(constant("c"), constant("d"))), - "a ** b + c ** d"); - assert!(exponentiate(subtract(constant("a"), constant("b")), - subtract(constant("c"), constant("d"))), - "(a - b) ** (c - d)"); - assert!(subtract(exponentiate(constant("a"), constant("b")), - exponentiate(constant("c"), constant("d"))), - "a ** b - c ** d"); + // Function + multiply + assert!(function("f", vec![multiply(a(), b())]), "f(a * b)"); + assert!(function("f", vec![multiply(a(), b()), multiply(c(), d()), multiply(e(), a())]), + "f(a * b, c * d, e * a)"); + + // Absolute value + multiply + assert!(absolute_value(multiply(a(), b())), "|a * b|"); + + // Negative + multiply + assert!(negative(multiply(a(), b())), "-(a * b)"); + + // Exponentiate + multiply + assert!(exponentiate(multiply(a(), b()), multiply(c(), d())), "(a * b) ** (c * d)"); + + // Multiply + multiply + assert!(multiply(multiply(a(), b()), multiply(c(), d())), "a * b * c * d"); + + // Divide + multiply + assert!(divide(multiply(a(), b()), multiply(c(), d())), "a * b / (c * d)"); + + // Modulo + multiply + assert!(modulo(multiply(a(), b()), multiply(c(), d())), "a * b % (c * d)"); + + // Add + multiply + assert!(add(multiply(a(), b()), multiply(c(), d())), "a * b + c * d"); + + // Subtract + multiply + assert!(subtract(multiply(a(), b()), multiply(c(), d())), "a * b - c * d"); } #[test] - fn format_combination_multiplicative_binary_operations_and_lower() + fn format_combinations_divide() { - assert!(multiply(multiply(constant("a"), constant("b")), - multiply(constant("c"), constant("d"))), - "a * b * c * d"); - assert!(multiply(divide(constant("a"), constant("b")), - divide(constant("c"), constant("d"))), - "a / b * c / d"); - assert!(multiply(modulo(constant("a"), constant("b")), - modulo(constant("c"), constant("d"))), - "a % b * (c % d)"); - assert!(divide(multiply(constant("a"), constant("b")), - multiply(constant("c"), constant("d"))), - "a * b / (c * d)"); - assert!(divide(divide(constant("a"), constant("b")), divide(constant("c"), constant("d"))), - "a / b / (c / d)"); - assert!(divide(modulo(constant("a"), constant("b")), modulo(constant("c"), constant("d"))), - "a % b / (c % d)"); - assert!(modulo(multiply(constant("a"), constant("b")), - multiply(constant("c"), constant("d"))), - "a * b % (c * d)"); - assert!(modulo(divide(constant("a"), constant("b")), divide(constant("c"), constant("d"))), - "a / b % (c / d)"); - assert!(modulo(modulo(constant("a"), constant("b")), modulo(constant("c"), constant("d"))), - "a % b % (c % d)"); - assert!(multiply(add(constant("a"), constant("b")), add(constant("c"), constant("d"))), - "(a + b) * (c + d)"); - assert!(add(multiply(constant("a"), constant("b")), multiply(constant("c"), constant("d"))), - "a * b + c * d"); - assert!(multiply(subtract(constant("a"), constant("b")), - subtract(constant("c"), constant("d"))), - "(a - b) * (c - d)"); - assert!(subtract(multiply(constant("a"), constant("b")), - multiply(constant("c"), constant("d"))), - "a * b - c * d"); - assert!(divide(add(constant("a"), constant("b")), add(constant("c"), constant("d"))), - "(a + b) / (c + d)"); - assert!(add(divide(constant("a"), constant("b")), divide(constant("c"), constant("d"))), - "a / b + c / d"); - assert!(divide(subtract(constant("a"), constant("b")), - subtract(constant("c"), constant("d"))), - "(a - b) / (c - d)"); - assert!(subtract(divide(constant("a"), constant("b")), - divide(constant("c"), constant("d"))), - "a / b - c / d"); - assert!(modulo(add(constant("a"), constant("b")), add(constant("c"), constant("d"))), - "(a + b) % (c + d)"); - assert!(add(modulo(constant("a"), constant("b")), modulo(constant("c"), constant("d"))), - "a % b + c % d"); - assert!(modulo(subtract(constant("a"), constant("b")), - subtract(constant("c"), constant("d"))), - "(a - b) % (c - d)"); - assert!(subtract(modulo(constant("a"), constant("b")), - modulo(constant("c"), constant("d"))), - "a % b - c % d"); + // Function + divide + assert!(function("f", vec![divide(a(), b())]), "f(a / b)"); + assert!(function("f", vec![divide(a(), b()), divide(c(), d()), divide(e(), a())]), + "f(a / b, c / d, e / a)"); + + // Absolute value + divide + assert!(absolute_value(divide(a(), b())), "|a / b|"); + + // Negative + divide + assert!(negative(divide(a(), b())), "-(a / b)"); + + // Exponentiate + divide + assert!(exponentiate(divide(a(), b()), divide(c(), d())), "(a / b) ** (c / d)"); + + // Multiply + divide + assert!(multiply(divide(a(), b()), divide(c(), d())), "a / b * c / d"); + + // Divide + divide + assert!(divide(divide(a(), b()), divide(c(), d())), "a / b / (c / d)"); + + // Modulo + divide + assert!(modulo(divide(a(), b()), divide(c(), d())), "a / b % (c / d)"); + + // Add + divide + assert!(add(divide(a(), b()), divide(c(), d())), "a / b + c / d"); + + // Subtract + divide + assert!(subtract(divide(a(), b()), divide(c(), d())), "a / b - c / d"); } #[test] - fn format_combination_additive_binary_operations_and_lower() + fn format_combinations_modulo() { - assert!(add(add(constant("a"), constant("b")), add(constant("c"), constant("d"))), - "a + b + c + d"); - assert!(add(subtract(constant("a"), constant("b")), subtract(constant("c"), constant("d"))), - "a - b + c - d"); - assert!(subtract(add(constant("a"), constant("b")), add(constant("c"), constant("d"))), - "a + b - (c + d)"); - assert!(subtract(subtract(constant("a"), constant("b")), - subtract(constant("c"), constant("d"))), - "a - b - (c - d)"); + // Function + modulo + assert!(function("f", vec![modulo(a(), b())]), "f(a % b)"); + assert!(function("f", vec![modulo(a(), b()), modulo(c(), d()), modulo(e(), a())]), + "f(a % b, c % d, e % a)"); + + // Absolute value + modulo + assert!(absolute_value(modulo(a(), b())), "|a % b|"); + + // Negative + modulo + assert!(negative(modulo(a(), b())), "-(a % b)"); + + // Exponentiate + modulo + assert!(exponentiate(modulo(a(), b()), modulo(c(), d())), "(a % b) ** (c % d)"); + + // Multiply + modulo + assert!(multiply(modulo(a(), b()), modulo(c(), d())), "a % b * (c % d)"); + + // Divide + modulo + assert!(divide(modulo(a(), b()), modulo(c(), d())), "a % b / (c % d)"); + + // Modulo + modulo + assert!(modulo(modulo(a(), b()), modulo(c(), d())), "a % b % (c % d)"); + + // Add + modulo + assert!(add(modulo(a(), b()), modulo(c(), d())), "a % b + c % d"); + + // Subtract + modulo + assert!(subtract(modulo(a(), b()), modulo(c(), d())), "a % b - c % d"); + } + + #[test] + fn format_combinations_add() + { + // Function + add + assert!(function("f", vec![add(a(), b())]), "f(a + b)"); + assert!(function("f", vec![add(a(), b()), add(c(), d()), add(e(), a())]), + "f(a + b, c + d, e + a)"); + + // Absolute value + add + assert!(absolute_value(add(a(), b())), "|a + b|"); + + // Negative + add + assert!(negative(add(a(), b())), "-(a + b)"); + + // Exponentiate + add + assert!(exponentiate(add(a(), b()), add(c(), d())), "(a + b) ** (c + d)"); + + // Multiply + add + assert!(multiply(add(a(), b()), add(c(), d())), "(a + b) * (c + d)"); + + // Divide + add + assert!(divide(add(a(), b()), add(c(), d())), "(a + b) / (c + d)"); + + // Modulo + add + assert!(modulo(add(a(), b()), add(c(), d())), "(a + b) % (c + d)"); + + // Add + add + assert!(add(add(a(), b()), add(c(), d())), "a + b + c + d"); + + // Subtract + add + assert!(subtract(add(a(), b()), add(c(), d())), "a + b - (c + d)"); + } + + #[test] + fn format_combinations_subtract() + { + // Function + subtract + assert!(function("f", vec![subtract(a(), b())]), "f(a - b)"); + assert!(function("f", vec![subtract(a(), b()), subtract(c(), d()), subtract(e(), a())]), + "f(a - b, c - d, e - a)"); + + // Absolute value + subtract + assert!(absolute_value(subtract(a(), b())), "|a - b|"); + + // Negative + subtract + assert!(negative(subtract(a(), b())), "-(a - b)"); + + // Exponentiate + subtract + assert!(exponentiate(subtract(a(), b()), subtract(c(), d())), "(a - b) ** (c - d)"); + + // Multiply + subtract + assert!(multiply(subtract(a(), b()), subtract(c(), d())), "(a - b) * (c - d)"); + + // Divide + subtract + assert!(divide(subtract(a(), b()), subtract(c(), d())), "(a - b) / (c - d)"); + + // Modulo + subtract + assert!(modulo(subtract(a(), b()), subtract(c(), d())), "(a - b) % (c - d)"); + + // Add + subtract + assert!(add(subtract(a(), b()), subtract(c(), d())), "a - b + c - d"); + + // Subtract + subtract + assert!(subtract(subtract(a(), b()), subtract(c(), d())), "a - b - (c - d)"); } }