Select Git revision
test_FunctionProcessor.cpp
test_FunctionProcessor.cpp 21.51 KiB
#include <catch2/catch.hpp>
#include <language/ast/ASTBuilder.hpp>
#include <language/ast/ASTModulesImporter.hpp>
#include <language/ast/ASTNodeDataTypeBuilder.hpp>
#include <language/ast/ASTNodeDeclarationToAffectationConverter.hpp>
#include <language/ast/ASTNodeExpressionBuilder.hpp>
#include <language/ast/ASTNodeTypeCleaner.hpp>
#include <language/ast/ASTSymbolTableBuilder.hpp>
#include <utils/Demangle.hpp>
#include <pegtl/string_input.hpp>
#include <sstream>
#define CHECK_FUNCTION_EVALUATION_RESULT(data, variable_name, expected_value) \
{ \
TAO_PEGTL_NAMESPACE::string_input input{data, "test.pgs"}; \
auto ast = ASTBuilder::build(input); \
\
ASTModulesImporter{*ast}; \
ASTNodeTypeCleaner<language::import_instruction>{*ast}; \
\
ASTSymbolTableBuilder{*ast}; \
ASTNodeDataTypeBuilder{*ast}; \
\
ASTNodeDeclarationToAffectationConverter{*ast}; \
ASTNodeTypeCleaner<language::var_declaration>{*ast}; \
ASTNodeTypeCleaner<language::fct_declaration>{*ast}; \
\
ASTNodeExpressionBuilder{*ast}; \
ExecutionPolicy exec_policy; \
ast->execute(exec_policy); \
\
auto symbol_table = ast->m_symbol_table; \
\
using namespace TAO_PEGTL_NAMESPACE; \
position use_position{internal::iterator{"fixture"}, "fixture"}; \
use_position.byte = 10000; \
auto [symbol, found] = symbol_table->find(variable_name, use_position); \
\
auto attributes = symbol->attributes(); \
auto value = std::get<decltype(expected_value)>(attributes.value()); \
\
REQUIRE(value == expected_value); \
}
// clazy:excludeall=non-pod-global-static
TEST_CASE("FunctionProcessor", "[language]")
{
SECTION("Scalar functions")
{
SECTION("-> B")
{
SECTION("B -> B")
{
SECTION("from B")
{
std::string_view data = R"(
let f : B -> B, b -> not b;
let b:B, b = f(true);
)";
CHECK_FUNCTION_EVALUATION_RESULT(data, "b", false);
}
}
SECTION("N -> B")
{
SECTION("from B")
{
std::string_view data = R"(
let f : N -> B, n -> n > 2;
let b:B, b = f(true);
)";
CHECK_FUNCTION_EVALUATION_RESULT(data, "b", false);
}
SECTION("from N")
{
std::string_view data = R"(
let f : N -> B, n -> n > 2;
let n:N, n = 3;
let b:B, b = f(n);
)";
CHECK_FUNCTION_EVALUATION_RESULT(data, "b", true);
}
SECTION("from Z")
{
std::string_view data = R"(
let f : N -> B, (n) -> (n > 2);
let b:B, b = f(2);
)";
CHECK_FUNCTION_EVALUATION_RESULT(data, "b", false);
}
}
SECTION("Z -> B")
{
SECTION("from B")
{
std::string_view data = R"(
let f : Z -> B, z -> z-3 >= 0;
let b:B, b = f(true);
)";
CHECK_FUNCTION_EVALUATION_RESULT(data, "b", false);
}
SECTION("from N")
{
std::string_view data = R"(
let f : Z -> B, z -> z-3 >= 0;
let n:N, n = 3;
let b:B, b = f(n);
)";
CHECK_FUNCTION_EVALUATION_RESULT(data, "b", true);
}
SECTION("from Z")
{
std::string_view data = R"(
let f : Z -> B, z -> (z-3 >= 0);
let b:B, b = f(2);
)";
CHECK_FUNCTION_EVALUATION_RESULT(data, "b", false);
}
}
SECTION("R -> B")
{
SECTION("from B")
{
std::string_view data = R"(
let f : R -> B, x -> x*x < 4;
let b:B, b = f(true);
)";
CHECK_FUNCTION_EVALUATION_RESULT(data, "b", true);
}
SECTION("from N")
{
std::string_view data = R"(
let f : R -> B, x -> x*x < 4;
let n:N, n = 3;
let b:B, b = f(n);
)";
CHECK_FUNCTION_EVALUATION_RESULT(data, "b", false);
}
SECTION("from Z")
{
std::string_view data = R"(
let f : R -> B, x -> x*x < 4;
let b:B, b = f(-2);
)";
CHECK_FUNCTION_EVALUATION_RESULT(data, "b", false);
}
SECTION("from R")
{
std::string_view data = R"(
let f : R -> B, x -> x*x < 4;
let b:B, b = f(-1.3);
)";
CHECK_FUNCTION_EVALUATION_RESULT(data, "b", true);
}
}
}
SECTION("-> N")
{
SECTION("from N*N")
{
std::string_view data = R"(
let f : N*N -> N, (m,n) -> m*n;
let n:N, n = f(2,4);
)";
CHECK_FUNCTION_EVALUATION_RESULT(data, "n", 8ul);
}
SECTION("from Z*Z")
{
std::string_view data = R"(
let f : Z*Z -> N, (p,q) -> p*q;
let n:N, n = f(-2,-4);
)";
CHECK_FUNCTION_EVALUATION_RESULT(data, "n", 8ul);
}
}
SECTION("-> Z")
{
SECTION("from N*N")
{
std::string_view data = R"(
let f : N*N -> Z, (m,n) -> m*n;
let z:Z, z = f(2,4);
)";
CHECK_FUNCTION_EVALUATION_RESULT(data, "z", 8l);
}
SECTION("from Z*Z")
{
std::string_view data = R"(
let f : Z*Z -> Z, (p,q) -> p*q;
let z:Z, z = f(-2,4);
)";
CHECK_FUNCTION_EVALUATION_RESULT(data, "z", -8l);
}
SECTION("from R*Z")
{
std::string_view data = R"(
let f : R*Z -> R, (p,q) -> p*q;
let x:R, x = f(-0.5,8);
)";
CHECK_FUNCTION_EVALUATION_RESULT(data, "x", double{-0.5 * 8l});
}
}
SECTION("-> R")
{
SECTION("from N*R")
{
std::string_view data = R"(
let f : N*R -> R, (n,x) -> n*x;
let r:R, r = f(2,4.2);
)";
CHECK_FUNCTION_EVALUATION_RESULT(data, "r", double{2ul * 4.2});
}
SECTION("from R")
{
std::string_view data = R"(
let f : R -> R, x -> x*x-1;
let r:R, r = f(4);
)";
CHECK_FUNCTION_EVALUATION_RESULT(data, "r", double{15});
}
SECTION("from R using global variable")
{
std::string_view data = R"(
let x0:R, x0 = 3;
let f : R -> R, x -> x-x0;
let x:R, x = f(7.3);
)";
CHECK_FUNCTION_EVALUATION_RESULT(data, "x", double{7.3 - 3});
}
}
SECTION("-> string")
{
SECTION("from string")
{
std::string_view data = R"(
let f : string -> string, s -> s+"bar";
let s:string, s = f("foo");
)";
CHECK_FUNCTION_EVALUATION_RESULT(data, "s", std::string{"foobar"});
}
SECTION("from string*N")
{
std::string_view data = R"(
let f : string*N -> string, (s,n) -> s+n;
let s:string, s = f("id", 2);
)";
CHECK_FUNCTION_EVALUATION_RESULT(data, "s", std::string{"id2"});
}
SECTION("from string*N (with conversion)")
{
std::string_view data = R"(
let f : string*N -> string, (s,n) -> s+n;
let s:string, s = f(3, 2);
)";
CHECK_FUNCTION_EVALUATION_RESULT(data, "s", std::string{"32"});
}
SECTION("from N (with conversion)")
{
std::string_view data = R"(
let f : N -> string, n -> n;
let s:string, s = f(3);
)";
CHECK_FUNCTION_EVALUATION_RESULT(data, "s", std::string{"3"});
}
}
}
SECTION("multi-expression functions")
{
SECTION(" -> N*R")
{
std::string_view data = R"(
let f : N -> N*R, n -> (2*n, 0.3*n);
let (n,x):N*R, (n,x) = f(2);
)";
CHECK_FUNCTION_EVALUATION_RESULT(data, "n", uint64_t{4});
CHECK_FUNCTION_EVALUATION_RESULT(data, "x", double{0.3 * int64_t{2}});
}
SECTION(" -> N*R*B")
{
std::string_view data = R"(
let f : N -> N*R*B, n -> (2*n, 0.3*n, 1.4*n>n*n);
let (n,x,b):N*R*B, (n,x,b) = f(2);
)";
CHECK_FUNCTION_EVALUATION_RESULT(data, "n", uint64_t{4});
CHECK_FUNCTION_EVALUATION_RESULT(data, "x", double{0.3 * int64_t{2}});
CHECK_FUNCTION_EVALUATION_RESULT(data, "b", false);
}
}
SECTION("multi-expression functions with flattening")
{
SECTION(" -> N*R")
{
std::string_view data = R"(
let f : N -> N, n -> 2*n;
let (x,n):R*N, (x,n) = (2.3, f(3));
)";
CHECK_FUNCTION_EVALUATION_RESULT(data, "n", uint64_t{6});
CHECK_FUNCTION_EVALUATION_RESULT(data, "x", double{2.3});
}
SECTION(" -> N*R*B")
{
std::string_view data = R"(
import math;
let f : N -> N*R, n -> (2*n, 0.3*n);
let (n,x,s):N*R*R, (n,x,s) = (f(2), sin(1));
)";
CHECK_FUNCTION_EVALUATION_RESULT(data, "n", uint64_t{4});
CHECK_FUNCTION_EVALUATION_RESULT(data, "x", double{0.3 * int64_t{2}});
CHECK_FUNCTION_EVALUATION_RESULT(data, "s", double{std::sin(1)});
}
}
SECTION("R^d functions (single value)")
{
SECTION(" R^1 -> R^1")
{
std::string_view data = R"(
let f : R^1 -> R^1, x -> 2*x;
let x:R^1, x = 3;
let fx:R^1, fx = f(x);
)";
CHECK_FUNCTION_EVALUATION_RESULT(data, "fx", (2 * TinyVector<1>{3}));
}
SECTION(" R^2 -> R^2")
{
std::string_view data = R"(
let f : R^2 -> R^2, x -> 2*x;
let x:R^2, x = (3, 7);
let fx:R^2, fx = f(x);
)";
CHECK_FUNCTION_EVALUATION_RESULT(data, "fx", (2 * TinyVector<2>{3, 7}));
}
SECTION(" R^3 -> R^3")
{
std::string_view data = R"(
let f : R^3 -> R^3, x -> 2*x;
let x:R^3, x = (2, 4, 7);
let fx:R^3, fx = f(x);
)";
CHECK_FUNCTION_EVALUATION_RESULT(data, "fx", (2 * TinyVector<3>{2, 4, 7}));
}
SECTION(" R -> R^1")
{
std::string_view data = R"(
let f : R -> R^1, x -> 2*x;
let x:R, x = 3;
let fx:R^1, fx = f(x);
)";
CHECK_FUNCTION_EVALUATION_RESULT(data, "fx", (2 * TinyVector<1>{3}));
}
SECTION(" R*R -> R^2")
{
std::string_view data = R"(
let f : R*R -> R^2, (x,y) -> (2*x, 3*y);
let fx:R^2, fx = f(2, 3);
)";
CHECK_FUNCTION_EVALUATION_RESULT(data, "fx", (TinyVector<2>{2 * 2, 3 * 3}));
}
SECTION(" R -> R^3")
{
std::string_view data = R"(
let f : R -> R^3, x -> (x, 2*x, x*x);
let fx:R^3, fx = f(3);
)";
CHECK_FUNCTION_EVALUATION_RESULT(data, "fx", (TinyVector<3>{3, 6, 9}));
}
}
SECTION("R^dxd functions (single value)")
{
SECTION(" R^1x1 -> R^1x1")
{
std::string_view data = R"(
let f : R^1x1 -> R^1x1, x -> 2*x;
let x:R^1x1, x = 3;
let fx:R^1x1, fx = f(x);
)";
CHECK_FUNCTION_EVALUATION_RESULT(data, "fx", (2 * TinyMatrix<1>{3}));
}
SECTION(" R^2x2 -> R^2x2")
{
std::string_view data = R"(
let f : R^2x2 -> R^2x2, x -> 2*x;
let x:R^2x2, x = (3, 7, 6, -2);
let fx:R^2x2, fx = f(x);
)";
CHECK_FUNCTION_EVALUATION_RESULT(data, "fx", (2 * TinyMatrix<2>{3, 7, 6, -2}));
}
SECTION(" R^3x3 -> R^3x3")
{
std::string_view data = R"(
let f : R^3x3 -> R^3x3, x -> 2*x;
let x:R^3x3, x = (2, 4, 7, 1, 3, 5, -6, 2, -3);
let fx:R^3x3, fx = f(x);
)";
CHECK_FUNCTION_EVALUATION_RESULT(data, "fx", (2 * TinyMatrix<3>{2, 4, 7, 1, 3, 5, -6, 2, -3}));
}
SECTION(" R -> R^1x1")
{
std::string_view data = R"(
let f : R -> R^1x1, x -> 2*x;
let x:R, x = 3;
let fx:R^1x1, fx = f(x);
)";
CHECK_FUNCTION_EVALUATION_RESULT(data, "fx", (2 * TinyMatrix<1>{3}));
}
SECTION(" R*R -> R^2x2")
{
std::string_view data = R"(
let f : R*R -> R^2x2, (x,y) -> (2*x, 3*y, 5*(x-y), 2*x-y);
let fx:R^2x2, fx = f(2, 3);
)";
const double x = 2;
const double y = 3;
CHECK_FUNCTION_EVALUATION_RESULT(data, "fx", (TinyMatrix<2>{2 * x, 3 * y, 5 * (x - y), 2 * x - y}));
}
SECTION(" R -> R^3x3")
{
std::string_view data = R"(
let f : R -> R^3x3, x -> (x, 2*x, x*x, 3*x, 2+x, x-1, x+0.5, 2*x-1, 1/x);
let fx:R^3x3, fx = f(3);
)";
const double x = 3;
CHECK_FUNCTION_EVALUATION_RESULT(data, "fx",
(TinyMatrix<3>{x, 2 * x, x * x, 3 * x, 2 + x, x - 1, x + 0.5, 2 * x - 1,
1 / x}));
}
}
SECTION("multi-expression functions (using R^d)")
{
SECTION(" R -> R*R^1*R^2*R^3")
{
std::string_view data = R"(
let f : R -> R*R^1*R^2*R^3, x -> (x+1, 2*x, (x-2, x+2), (1, 0.5*x, x*x));
let (x, x1, x2, x3):R*R^1*R^2*R^3, (x, x1, x2, x3) = f(3);
)";
const double x = 3;
CHECK_FUNCTION_EVALUATION_RESULT(data, "x", (double{x + 1}));
CHECK_FUNCTION_EVALUATION_RESULT(data, "x1", (TinyVector<1>{2 * x}));
CHECK_FUNCTION_EVALUATION_RESULT(data, "x2", (TinyVector<2>{x - 2, x + 2}));
CHECK_FUNCTION_EVALUATION_RESULT(data, "x3", (TinyVector<3>{1, 0.5 * x, x * x}));
}
SECTION(" R^2*R^3 -> R*R^1*R^2*R^3")
{
std::string_view data = R"(
let f : R^2*R^3 -> R*R^1*R^2*R^3,
(x2, x3) -> (x2[0]+x3[2], x3[1], (x3[0], x2[1]), (x3[0], x3[0]+x2[1], x3[2]));
let y2:R^2, y2 = (2.3, 4.1);
let y3:R^3, y3 = (1.2, 1.3, 2.1);
let(x, x1, x2, x3) : R*R^1*R^2*R^3, (x, x1, x2, x3) = f(y2, y3);
)";
TinyVector<2> y2{2.3, 4.1};
TinyVector<3> y3{1.2, 1.3, 2.1};
CHECK_FUNCTION_EVALUATION_RESULT(data, "x", (double{y2[0] + y3[2]}));
CHECK_FUNCTION_EVALUATION_RESULT(data, "x1", (TinyVector<1>{y3[1]}));
CHECK_FUNCTION_EVALUATION_RESULT(data, "x2", (TinyVector<2>{y3[0], y2[1]}));
CHECK_FUNCTION_EVALUATION_RESULT(data, "x3", (TinyVector<3>{y3[0], y3[0] + y2[1], y3[2]}));
}
SECTION(" R^2*R^3 -> R*R^1*R^2*R^3 [with 0 as argument]")
{
std::string_view data = R"(
let f : R^2*R^3 -> R*R^1*R^2*R^3,
(x2, x3) -> (x2[0]+x3[2], x3[1], (x3[0], x2[1]), (x3[0], x3[0]+x2[1], x3[2]));
let y2:R^2, y2 = (2.3, 4.1);
let (x, x1, x2, x3) : R*R^1*R^2*R^3, (x, x1, x2, x3) = f(y2, 0);
)";
TinyVector<2> y2{2.3, 4.1};
TinyVector<3> y3{zero};
CHECK_FUNCTION_EVALUATION_RESULT(data, "x", (double{y2[0] + y3[2]}));
CHECK_FUNCTION_EVALUATION_RESULT(data, "x1", (TinyVector<1>{y3[1]}));
CHECK_FUNCTION_EVALUATION_RESULT(data, "x2", (TinyVector<2>{y3[0], y2[1]}));
CHECK_FUNCTION_EVALUATION_RESULT(data, "x3", (TinyVector<3>{y3[0], y3[0] + y2[1], y3[2]}));
}
SECTION(" R^2*R^3 -> R*R^1*R^2*R^3 [with 0 in result]")
{
std::string_view data = R"(
let f : R^2*R^3 -> R*R^1*R^2*R^3,
(x2, x3) -> (x2[0]+x3[2], x3[1], 0, 0);
let y2:R^2, y2 = (2.3, 4.1);
let (x, x1, x2, x3):R*R^1*R^2*R^3, (x, x1, x2, x3) = f(y2, 0);
)";
TinyVector<2> y2{2.3, 4.1};
TinyVector<3> y3{zero};
CHECK_FUNCTION_EVALUATION_RESULT(data, "x", (double{y2[0] + y3[2]}));
CHECK_FUNCTION_EVALUATION_RESULT(data, "x1", (TinyVector<1>{y3[1]}));
CHECK_FUNCTION_EVALUATION_RESULT(data, "x2", (TinyVector<2>{zero}));
CHECK_FUNCTION_EVALUATION_RESULT(data, "x3", (TinyVector<3>{zero}));
}
}
SECTION("multi-expression functions (using R^dxd)")
{
SECTION(" R -> R*R^1x1*R^2x2*R^3x3")
{
std::string_view data = R"(
let f : R -> R*R^1x1*R^2x2*R^3x3, x -> (x+1, 2*x, (x-2, x+2, 3, 2), (1, 0.5*x, x*x, x+1, 1/x, 2, x*x, 2*x-1, 3*x));
let (x, x11, x22, x33):R*R^1x1*R^2x2*R^3x3, (x, x11, x22, x33) = f(3);
)";
const double x = 3;
CHECK_FUNCTION_EVALUATION_RESULT(data, "x", (double{x + 1}));
CHECK_FUNCTION_EVALUATION_RESULT(data, "x11", (TinyMatrix<1>{2 * x}));
CHECK_FUNCTION_EVALUATION_RESULT(data, "x22", (TinyMatrix<2>{x - 2, x + 2, 3, 2}));
CHECK_FUNCTION_EVALUATION_RESULT(data, "x33",
(TinyMatrix<3>{1, 0.5 * x, x * x, x + 1, 1 / x, 2, x * x, 2 * x - 1, 3 * x}));
}
SECTION(" R^2x2*R^3x3 -> R*R^1x1*R^2x2*R^3x3")
{
std::string_view data = R"(
let f : R^2x2*R^3x3 -> R*R^1x1*R^2x2*R^3x3,
(x22, x33) -> (x22[0,0]+x33[2,0], x33[1,2], (x33[0,1], x22[1,1], x22[0,0], x33[2,2]), x22[0,0]*x33);
let y22:R^2x2, y22 = (2.3, 4.1, 6, -3);
let y33:R^3x3, y33 = (1.2, 1.3, 2.1, 3.2, -1.5, 2.3, -0.2, 3.1, -2.6);
let(x, x11, x22, x33) : R*R^1x1*R^2x2*R^3x3, (x, x11, x22, x33) = f(y22, y33);
)";
const TinyMatrix<2> x22{2.3, 4.1, 6, -3};
const TinyMatrix<3> x33{1.2, 1.3, 2.1, 3.2, -1.5, 2.3, -0.2, 3.1, -2.6};
CHECK_FUNCTION_EVALUATION_RESULT(data, "x", (double{x22(0, 0) + x33(2, 0)}));
CHECK_FUNCTION_EVALUATION_RESULT(data, "x11", (TinyMatrix<1>{x33(1, 2)}));
CHECK_FUNCTION_EVALUATION_RESULT(data, "x22", (TinyMatrix<2>{x33(0, 1), x22(1, 1), x22(0, 0), x33(2, 2)}));
CHECK_FUNCTION_EVALUATION_RESULT(data, "x33", (TinyMatrix<3>{x22(0, 0) * x33}));
}
SECTION(" R^2x2*R^3x3 -> R*R^1x1*R^2x2*R^3x3 [with 0 as argument]")
{
std::string_view data = R"(
let f : R^2x2*R^3x3 -> R*R^1x1*R^2x2*R^3x3,
(x22, x33) -> (x22[0,0]+x33[2,1], x33[1,2], (x33[0,1], x22[1,0], x22[0,1], x33[2,2]),
(x22[1,0], x33[0,2]+x22[1,1], x33[2,2],
x33[2,0], x33[2,0]+x22[0,0], x33[1,1],
x33[2,1], x33[1,2]+x22[1,1], x33[0,0]));
let y22:R^2x2, y22 = (2.3, 4.1, 3.1, 1.7);
let y33:R^3x3, y33 = (2.7, 3.1, 2.1,
0.3, 1.2, 1.6,
1.7, 2.2, 1.4);
let (x, x11, x22, x33) : R*R^1x1*R^2x2*R^3x3, (x, x11, x22, x33) = f(y22, y33);
)";
TinyMatrix<2> x22{2.3, 4.1, 3.1, 1.7};
TinyMatrix<3> x33{2.7, 3.1, 2.1, 0.3, 1.2, 1.6, 1.7, 2.2, 1.4};
CHECK_FUNCTION_EVALUATION_RESULT(data, "x", (double{x22(0, 0) + x33(2, 1)}));
CHECK_FUNCTION_EVALUATION_RESULT(data, "x11", (TinyMatrix<1>{x33(1, 2)}));
CHECK_FUNCTION_EVALUATION_RESULT(data, "x22", (TinyMatrix<2>{x33(0, 1), x22(1, 0), x22(0, 1), x33(2, 2)}));
CHECK_FUNCTION_EVALUATION_RESULT(data, "x33",
(TinyMatrix<3>{x22(1, 0), x33(0, 2) + x22(1, 1), x33(2, 2), x33(2, 0),
x33(2, 0) + x22(0, 0), x33(1, 1), x33(2, 1),
x33(1, 2) + x22(1, 1), x33(0, 0)}));
}
SECTION(" R^2x2*R^3x3 -> R*R^1x1*R^2x2*R^3x3 [with 0 in result]")
{
std::string_view data = R"(
let f : R^2x2*R^3x3 -> R*R^1x1*R^2x2*R^3x3,
(x22, x33) -> (x22[0,0]+x33[2,0], x33[1,1], 0, 0);
let y22:R^2x2, y22 = (2.3, 4.1, 3.1, 1.7);
let (x, x11, x22, x33):R*R^1x1*R^2x2*R^3x3, (x, x11, x22, x33) = f(y22, 0);
)";
TinyMatrix<2> x22{2.3, 4.1, 3.1, 1.7};
TinyMatrix<3> x33{zero};
CHECK_FUNCTION_EVALUATION_RESULT(data, "x", (double{x22(0, 0) + x33(2, 0)}));
CHECK_FUNCTION_EVALUATION_RESULT(data, "x11", (TinyMatrix<1>{x33(1, 1)}));
CHECK_FUNCTION_EVALUATION_RESULT(data, "x22", (TinyMatrix<2>{zero}));
CHECK_FUNCTION_EVALUATION_RESULT(data, "x33", (TinyMatrix<3>{zero}));
}
}
SECTION("function composition")
{
SECTION("N -> N -> R")
{
std::string_view data = R"(
let f : N -> N, n -> 2*n;
let g : N -> R, n -> 2*n+0.5;
let x:R, x = g(f(3));
)";
CHECK_FUNCTION_EVALUATION_RESULT(data, "x", double{(2 * 3) * 2 + 0.5});
}
SECTION("R -> R*R -> R")
{
std::string_view data = R"(
import math;
let f : N -> N, n -> 2*n;
let g : N -> R, n -> sin(2*n)+0.5;
let x:R, x = g(f(3));
)";
CHECK_FUNCTION_EVALUATION_RESULT(data, "x", double{std::sin((2 * 3) * 2) + 0.5});
}
SECTION("R -> R*R -> R")
{
std::string_view data = R"(
import math;
let f : R -> R*R, x -> (x+1, x*2);
let x:R, x = pow(f(2));
)";
CHECK_FUNCTION_EVALUATION_RESULT(data, "x", double{std::pow(2. + 1, 2. * 2)});
}
SECTION("R -> R^2 -> R")
{
std::string_view data = R"(
let f : R -> R^2, x -> (x+1, x*2);
let g : R^2 -> R, x -> x[0] + x[1];
let x:R, x = g(f(3));
)";
double x0 = 3;
CHECK_FUNCTION_EVALUATION_RESULT(data, "x", double{x0 + 1 + x0 * 2});
}
SECTION("R -> R^2*R^3 -> R")
{
std::string_view data = R"(
let f : R -> R^2*R^3, x -> ((x+1, x*2), (6*x, 7-x, x/2.3));
let g : R^2*R^3 -> R, (x, y) -> x[0]*x[1] + y[0]*y[1]-y[2];
let x:R, x = g(f(3));
)";
double x0 = 3;
CHECK_FUNCTION_EVALUATION_RESULT(data, "x", double{(x0 + 1) * x0 * 2 + 6 * x0 * (7 - x0) - x0 / 2.3});
}
SECTION("R -> R^2x2 -> R")
{
std::string_view data = R"(
let f : R -> R^2x2, x -> (x+1, x*2, x-1, x);
let g : R^2x2 -> R, A -> A[0,0] + 2*A[1,1] + 3*A[0,1]+ A[1, 0];
let x:R, x = g(f(3));
)";
const double x = 3;
const TinyMatrix<2> A{x + 1, x * 2, x - 1, x};
CHECK_FUNCTION_EVALUATION_RESULT(data, "x", double{A(0, 0) + 2 * A(1, 1) + 3 * A(0, 1) + A(1, 0)});
}
SECTION("R -> R^2x2*R^3x3 -> R")
{
std::string_view data = R"(
let f : R -> R^2x2*R^3x3, x -> ((x+1, x*2, x-1, x), (6*x, 7-x, x/2.3, -x, 2*x, x/2.5, x*x, 2*x, x));
let g : R^2x2*R^3x3 -> R, (A22, A33) -> A22[0,0]*A22[1,1] + (A33[0,0]*A33[1,0]-A33[2,2])*A22[0,1]-A33[2,0]*A33[0,2]-A22[1,1];
let x:R, x = g(f(3));
)";
const double x = 3;
const TinyMatrix<2> A22{x + 1, x * 2, x - 1, x};
const TinyMatrix<3> A33{6 * x, 7 - x, x / 2.3, -x, 2 * x, x / 2.5, x * x, 2 * x, x};
CHECK_FUNCTION_EVALUATION_RESULT(data, "x",
double{A22(0, 0) * A22(1, 1) + (A33(0, 0) * A33(1, 0) - A33(2, 2)) * A22(0, 1) -
A33(2, 0) * A33(0, 2) - A22(1, 1)});
}
}
}