Skip to content

Commit

Permalink
Math generator: add limit (#60)
Browse files Browse the repository at this point in the history
Bug:#56
  • Loading branch information
ArthurSonzogni authored Jan 24, 2023
1 parent 0781d8f commit 413132b
Show file tree
Hide file tree
Showing 10 changed files with 207 additions and 39 deletions.
1 change: 0 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ endif()

FetchContent_Declare(antlr
GIT_REPOSITORY https://github.com/antlr/antlr4
# GIT_TAG 4.11.1
GIT_TAG 1cb4669f84cea5b59661fd44b0f80509fdacd3f9
GIT_SHALLOW FALSE
GIT_PROGRESS TRUE
Expand Down
6 changes: 3 additions & 3 deletions snap/snapcraft.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ base: core20
icon: "./favicon.png"
apps:
diagon:
command: diagon
command: usr/local/bin/diagon

parts:
diagon:
Expand All @@ -31,8 +31,8 @@ parts:
- uuid-dev
- openjdk-11-jdk
- libboost-graph-dev
override-build: |
snapcraftctl build
override-pull: |
snapcraftctl pull
snapcraftctl set-version "$(git rev-list --count HEAD)"
cmake-parameters:
- -DCMAKE_INSTALL_PREFIX=/usr
Expand Down
178 changes: 144 additions & 34 deletions src/translator/math/Math.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ struct Style {
wchar_t multiply;
std::wstring lower_or_equal;
std::wstring greater_or_equal;
std::wstring lime;

wchar_t left_parenthesis_0;
wchar_t left_parenthesis_1;
Expand Down Expand Up @@ -76,8 +77,8 @@ Draw Parse(MathParser::ValueBangContext* context, Style*, bool);
Draw Parse(MathParser::ValueContext*, Style*, bool suppress_parenthesis);
Draw Parse(MathParser::AtomContext*, Style*, bool suppress_parenthesis);
Draw Parse(MathParser::VariableContext*, Style* style);
Draw ComposeHorizontal(const Draw& left, const Draw& right, int spaces);
Draw ComposeVertical(const Draw& top, const Draw& down, int spaces);
Draw ComposeHorizontal(const Draw& left, const Draw& right, int spaces = 0);
Draw ComposeVertical(const Draw& top, const Draw& down, int spaces = 0);
Draw ComposeDiagonal(const Draw& A, const Draw& B);
Draw WrapWithParenthesis(const Draw& element, Style* style);
std::string to_string(const Draw& draw);
Expand Down Expand Up @@ -293,6 +294,7 @@ Draw Parse(MathParser::EquationContext* context, Style* style) {
else if (op->LE()) symbol = style->lower_or_equal;
else if (op->GE()) symbol = style->greater_or_equal;
else if (op->EQ()) symbol = L'=';
else if (op->LIME()) symbol = style->lime;
// clang-format on

int op_x = draw.dim_x + 1;
Expand All @@ -317,6 +319,7 @@ std::wstring ParseLatex(MathParser::EquationContext* context, Style* style) {
else if (op->GT()) out += L" > ";
else if (op->LE()) out += L" \\leq ";
else if (op->GE()) out += L" \\geq ";
else if (op->LIME()) out += L" \\to ";
else if (op->EQ()) out += L" = ";
// clang-format on

Expand Down Expand Up @@ -540,6 +543,57 @@ std::wstring ParseFunctionSumLatex(MathParser::FunctionContext* context,
return out + L" " + ParseLatex(context->equation(0), style);
}

bool CheckFunctionLimit(MathParser::FunctionContext* context) {
int num_arguments = context->equation().size();
if (num_arguments != 2) {
std::cerr << "Limit function (lim) only handle 2 arguments, but "
<< num_arguments << " provided" << std::endl;
return false;
}
return true;
}

Draw ParseFunctionLimit(MathParser::FunctionContext* context, Style* style) {
if (!CheckFunctionLimit(context))
return Draw(L"(error)");

Draw lim = Parse(context->variable(), style);
Draw down = Parse(context->equation(0), style);
Draw right = Parse(context->equation(1), style);

if (right.center_y == right.dim_y-1) {
Draw lim_right = ComposeHorizontal(lim, right, 1);
lim_right.center_x = 0;
down.center_x = 0;
Draw out = ComposeVertical(lim_right, down);
out.center_x = lim_right.dim_x - 1;
out.center_y = 0;
return out;
}

// Align center `lim` with `down`.
lim.center_x = 0;
down.center_x = 0;
Draw lim_down = ComposeVertical(std::move(lim), std::move(down));

// Align |lim_down| and right to the correct baseline.
lim_down.center_x = lim.dim_x / 2;
lim_down.center_y = 0;
right.center_x = right.dim_x / 2;
return ComposeHorizontal(std::move(lim_down), std::move(right), 1);
}

std::wstring ParseFunctionLimitLatex(MathParser::FunctionContext* context,
Style* style) {
if (!CheckFunctionLimit(context))
return L"(error)";

std::wstring out = L"\\lim";
if (context->equation(0))
out += L"_{" + ParseLatex(context->equation(0), style) + L"}";
return out + L" " + ParseLatex(context->equation(1), style);
}

bool CheckFunctionMult(MathParser::FunctionContext* context) {
int num_arguments = context->equation().size();
if (num_arguments > 3) {
Expand Down Expand Up @@ -799,6 +853,8 @@ Draw Parse(MathParser::FunctionContext* context, Style* style) {
return ParseFunctionSqrt(context, style);
if (function_name == "sum")
return ParseFunctionSum(context, style);
if (function_name == "lim")
return ParseFunctionLimit(context, style);
if (function_name == "int")
return ParseFunctionIntegral(context, style);
if (function_name == "mult")
Expand Down Expand Up @@ -834,6 +890,8 @@ std::wstring ParseLatex(MathParser::FunctionContext* context, Style* style) {
return ParseFunctionSqrtLatex(context, style);
if (function_name == "sum")
return ParseFunctionSumLatex(context, style);
if (function_name == "lim")
return ParseFunctionLimitLatex(context, style);
if (function_name == "int")
return ParseFunctionIntegralLatex(context, style);
if (function_name == "mult")
Expand Down Expand Up @@ -1064,38 +1122,88 @@ class Math : public Translator {

std::vector<Translator::Example> Examples() final {
return {
{"1-fraction", "f(x) = 1 + x / (1 + x)"},
{"2-square-root", "sqrt(1+sqrt(1+x/2))"},
{"3-power", "f(x) = 1 + x^2 + x^3 + x^(1+1/2)"},
{"4-subscript", "S_n = u_1 + u_2 + ... + u_n"},
{"5-summation", "sum(i^2,i=0,n) = n^3/2+n^2/2+n/6"},
{"6-integral", "int(x^2 * dx ,0,1) = n^3/3"},
{"7-product",
"mult(i^2,i=1,n) = (mult(i,i=1,n))^2\n\n\n\nmult(1/2,1,100) = "
"7.8886091e-31"},
{"8-vector", "[a;b] + [c;d] = [a+c; b+d]"},
{"9-matrix", "[1,2;3,4] * [x;y] = [1*x+2*y; 3*x+4*y]"},
{"10-factorial", "[n;k] = n! / (k! *(n-k)!)"},
{"11-quoted-string",
"\"x_n\"\n"
" x_n\n"},
{"12-braces-vs-parenthesis",
"A_(1+2)\n"
"\n"
"A_{1+2}\n"
"\n"
"A^{1+2}\n"},
{"13-Math-symbols",
"Alpha + alpha + Digamma + digamma + Kappa + kappa + Omicron \n"
"omicron + Upsilon + upsilon + Beta + beta + Zeta + zeta + Lambda \n"
"lambda + Pi + pi + Phi + phi + Gamma + gamma + Eta + eta + Mu + mu \n"
"Rho + rho + Chi + chi + Delta + delta + Theta + theta + Nu + nu \n"
"Sigma + sigma + Psi + psi + Epsilon + epsilon + Iota + iota + Xi\n"
"xi + Tau + tau + Omega + omega"},
{"14-mathbb",
"mathbb(R)\n\nbb(R)\n\nbb(ABCDEFGHIJKLMNOPQRSTUVWXYZ)\n\nbb("
"abcdefghijklmnopqrstuvwxyz)\n\nbb(0123456789)"},
{"100-continued-fraction", "psi = 1 + 1/(1+1/(1+1/(1+1/(1+...))))"},
{
"1-fraction",
"f(x) = 1 + x / (1 + x)",
},
{
"2-square-root",
"sqrt(1+sqrt(1+x/2))",
},
{
"3-power",
"f(x) = 1 + x^2 + x^3 + x^(1+1/2)",
},
{
"4-subscript",
"S_n = u_1 + u_2 + ... + u_n",
},
{
"5-summation",
"sum(i^2,i=0,n) = n^3/2+n^2/2+n/6",
},
{
"6-integral",
"int(x^2 * dx ,0,1) = n^3/3",
},
{
"7-product",
"mult(i^2,i=1,n) = (mult(i,i=1,n))^2\n\n\n\nmult(1/2,1,100) = "
"7.8886091e-31",
},
{
"8-vector",
"[a;b] + [c;d] = [a+c; b+d]",
},
{
"9-matrix",
"[1,2;3,4] * [x;y] = [1*x+2*y; 3*x+4*y]",
},
{
"10-factorial",
"[n;k] = n! / (k! *(n-k)!)",
},
{
"11-quoted-string",
"\"x_n\"\n"
" x_n\n",
},
{
"12-braces-vs-parenthesis",
"A_(1+2)\n"
"\n"
"A_{1+2,}\n"
"\n"
"A^{1+2,}\n",
},
{
"13-Math-symbols",
"Alpha + alpha + Digamma + digamma + Kappa + kappa + Omicron \n"
"omicron + Upsilon + upsilon + Beta + beta + Zeta + zeta + Lambda "
"\n"
"lambda + Pi + pi + Phi + phi + Gamma + gamma + Eta + eta + Mu + "
"mu \n"
"Rho + rho + Chi + chi + Delta + delta + Theta + theta + Nu + nu \n"
"Sigma + sigma + Psi + psi + Epsilon + epsilon + Iota + iota + Xi\n"
"xi + Tau + tau + Omega + omega",
},
{
"14-mathbb",
"mathbb(R)\n\nbb(R)\n\nbb(ABCDEFGHIJKLMNOPQRSTUVWXYZ)\n\nbb("
"abcdefghijklmnopqrstuvwxyz)\n\nbb(0123456789)",
},
{
"100-continued-fraction",
"psi = 1 + 1/(1+1/(1+1/(1+1/(1+...))))",
},
{
"15-limits",
"lim(x -> infinity, 1/x) = 0",
},
{
"100-continued-fraction",
"psi = 1 + 1/(1+1/(1+1/(1+1/(1+...))))",
},
};
}

Expand All @@ -1107,6 +1215,7 @@ class Math : public Translator {
style.divide = L'-';
style.multiply = L'.';
style.greater_or_equal = L">=";
style.lime= L"->";
style.lower_or_equal = L"<=";
style.left_parenthesis_0 = L'(';
style.left_parenthesis_1 = L'/';
Expand Down Expand Up @@ -1139,6 +1248,7 @@ class Math : public Translator {
// style.multiply = L'×';
style.multiply = L'';
style.greater_or_equal = L"";
style.lime= L"";
style.lower_or_equal = L"";

style.left_parenthesis_0 = L'(';
Expand Down
3 changes: 2 additions & 1 deletion src/translator/math/Math.g4
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ function : variable LPAREN equation (',' equation)* RPAREN ;
variable : VARIABLE;
matrix : LBRACKET matrixLine (';' matrixLine)* RBRACKET;
matrixLine : expression ( ',' expression ) *;
relop : EQ | GT | LT | GE | LE;
relop : EQ | GT | LT | GE | LE | LIME;
addop : PLUS | MINUS ;
mulop : TIMES | DIV ;
powop : POW | SUBSCRIPT ;
Expand All @@ -77,6 +77,7 @@ MINUS : '-' ;
TIMES : '*' ;
BANG: '!';
DIV : '/' ;
LIME : '->' ;
GT : '>' ;
LT : '<' ;
GE : '>=' ;
Expand Down
7 changes: 7 additions & 0 deletions test/Math/lim/input
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
lim(a,b)

lim(x->infinity, x) = infinity

lim(x->∞, sqrt(x+1/x)) = infinity

lim(x->∞, sqrt(x+1/x)) = 1/2
15 changes: 15 additions & 0 deletions test/Math/lim/output
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
lim b
a

lim x = ∞
x ⟶ ∞

_____
╱ 1
lim ╱ x + ─ = ∞
x ⟶ ∞ ╲╱ x

_____
╱ 1 1
lim ╱ x + ─ = ─
x ⟶ ∞ ╲╱ x 2
7 changes: 7 additions & 0 deletions test/Math_style=ASCII/lim/input
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
lim(a,b)

lim(x->infinity, x) = infinity

lim(x->∞, sqrt(x+1/x)) = infinity

lim(x->∞, sqrt(x+1/x)) = 1/2
15 changes: 15 additions & 0 deletions test/Math_style=ASCII/lim/output
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
lim b
a

lim x = ∞
x -> ∞

_____
/ 1
lim / x + - = ∞
x -> ∞ \/ x

_____
/ 1 1
lim / x + - = -
x -> ∞ \/ x 2
7 changes: 7 additions & 0 deletions test/Math_style=Latex/lim/input
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
lim(a,b)

lim(x->infinity, x) = infinity

lim(x->∞, sqrt(x+1/x)) = infinity

lim(x->∞, sqrt(x+1/x)) = 1/2
7 changes: 7 additions & 0 deletions test/Math_style=Latex/lim/output
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
\lim_{a} b \\
\\
\lim_{x \to \infty} x = \infty \\
\\
\lim_{x \to ∞} \sqrt{x + \frac{1}{x}} = \infty \\
\\
\lim_{x \to ∞} \sqrt{x + \frac{1}{x}} = \frac{1}{2}

0 comments on commit 413132b

Please sign in to comment.