Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

I have a program that generates bits of Tex code like these:

$\product{a}{\add{b}{c}}\leftrightarrow \add{\product{a}{b}}{\product{a}{c}}$
$\add{a}{\add{b}{c}}\leftrightarrow \add{\add{a}{b}}{c}$
$\product{a}{b}\leftrightarrow \product{b}{a}$
$\product{a}{\product{b}{c}}\leftrightarrow \product{\product{a}{b}}{c}$
$\subtract{\power{x}{\two}}{\power{y}{\two}}\leftrightarrow \product{\add{x}{y}}{\subtract{x}{y}}$

At the moment, I have defined

\newcommand\add[2]{({#1}+{#2})}
\newcommand\subtract[2]{({#1}-{#2})}
\newcommand\product[2]{({#1}{#2})}

But this results in far too many brackets being produced -- for example \sum{\product{a}{b}}{c} is rendered as ((ab)+c).

How can I define \add, \product and other arithmetic operations so that the minimum number of necessary brackets are added? Just to clarify, I want \product{a}{\add{b}{c}} to generate a(b+c), but \sum{\product{a}{b}}{c} to produce ab + c.

NB. If it was straightforward to do this in the code that generated the TeX, I would be doing so!

share|improve this question
1  
From prefix form to infix form with the usual conventions about precedence? I surely wouldn't undertake the task. ;-) –  egreg Feb 19 at 23:26
1  
I've done it in C++ in the past. (Currently using Haskell, where the key problem is that sum, etc. are stored purely as data.) At heart, this is a rendering issue and it would be very nice if it could be solved once and for all in a rendering language. But I have no idea how to start with the tools available in TeX... –  Mohan Feb 19 at 23:36
    
David Carlisle came up with an absolutely brilliant solution, but jfbu's tweak to it is in technical terms a clear improvement. Which should I accept? –  Mohan Feb 20 at 17:38

2 Answers 2

up vote 19 down vote accepted

Probably I don't have the precedence rules exactly as you need, but something like

enter image description here

\def\p{0}

\def\power#1#2{%
\ifnum\p>20(\fi
{\def\p{20}#1}^{\def\p{0}#2}%
\ifnum\p>20)\fi}

\def\product#1#2{%
\ifnum\p>20(\fi
{\def\p{20}#1#2}%
\ifnum\p>20)\fi}

\def\add#1#2{%
\ifnum\p>10(\fi
{\def\p{10}#1+#2}%
\ifnum\p>10)\fi}

\def\subtract#1#2{%
\ifnum\p>8(\fi
{\def\p{9}#1-#2}%
\ifnum\p>8)\fi}


\def\two{2}

$\product{a}{\add{b}{c}}\leftrightarrow \add{\product{a}{b}}{\product{a}{c}}$

$\add{a}{\add{b}{c}}\leftrightarrow \add{\add{a}{b}}{c}$

$\product{a}{b}\leftrightarrow \product{b}{a}$

$\product{a}{\product{b}{c}}\leftrightarrow \product{\product{a}{b}}{c}$

$\subtract{\power{x}{\two}}{\power{y}{\two}}\leftrightarrow \product{\add{x}{y}}{\subtract{x}{y}}$

$\subtract{a}{\subtract{b}{c}}$

$\subtract{\subtract{a}{b}}{c}$


\bye
share|improve this answer
    
Magnificent!!!! –  Steven B. Segletes Feb 20 at 0:26
    
Absolutely beautiful. Thank you. –  Mohan Feb 20 at 0:27
1  
@Mohan I just updated to fix a-b-c –  David Carlisle Feb 20 at 0:28
1  
$\subtract{\subtract{\subtract{a}{b}}{c}}{d}$ generates ((a − b) − c) − d but the minimal representation would be a-b-c-d. –  jfbu Feb 20 at 14:22
1  
and $\add{a}{\subtract{b}{c}}$ generates a + (b -c) where a + b - c is the minimal representation. –  jfbu Feb 20 at 14:29

This answer is initially motivated from David's answer. But to address the issues I raised in the comments a different perspective is needed.

I have not thoroughly tested the code does in all circumstances what is hoped for. The aim is to use as few parentheses as possible.

Update: the sentence about a different perspective is not quite exact. I started with a different perspective but in the end, looking at the result a bit later, I see that the code is only a slight evolution of David's answer. I have thus rewritten it in a style closer to that answer.

\def\p{0}

\def\power #1#2{% 
   \ifnum\p>3(\fi
     {\def\p{4}#1}^{\def\p{0}#2}%
   \ifnum\p>3)\fi
}

\def\product #1#2{% 
  \ifnum\p>2(\fi
   {\def\p{2}#1#2}% perhaps #1\cdot #2 would be better
  \ifnum\p>2)\fi
}

\def\add #1#2{%
  \ifnum\p>1(\fi
    {\def\p{0}#1+#2}%
  \ifnum\p>1)\fi
}

\def\subtract #1#2{%
  \ifnum\p>0(\fi
     {\def\p{0}#1-\def\p{2}#2}%
  \ifnum\p>0)\fi
}

\def\two{2}

$\product{a}{\add{b}{c}}\leftrightarrow \add{\product{a}{b}}{\product{a}{c}}$

$\add{a}{\product{b}{c}}$

$\add{a}{\product{b}{\subtract{c}{d}}}$

$\add{a}{\add{b}{c}}\leftrightarrow \add{\add{a}{b}}{c}$

$\product{a}{b}\leftrightarrow \product{b}{a}$

$\product{a}{\product{b}{c}}\leftrightarrow \product{\product{a}{b}}{c}$

$\subtract{\power{x}{\two}}{\power{y}{\two}}\leftrightarrow \product{\add{x}{y}}{\subtract{x}{y}}$

$\subtract{a}{\subtract{b}{c}}$

$\subtract{\subtract{a}{b}}{c}$

$\product{a}{\add{b}{c}}$ 

$\add{\product{a}{b}}{c}$


$\subtract{a}{\subtract{b}{\subtract{c}{d}}}$

$\subtract{\subtract{\subtract{a}{b}}{c}}{d}$

$\add{a}{\subtract{b}{c}}$

$\subtract{\add{a}{b}}{\add{c}{d}}$

$\add{\subtract{\add{a}{b}}{\add{c}{d}}}{\add{e}{f}}$

$\power{x}{\power{y}{z}}$

$\power{\power{x}{y}}{z}$

$\power{x}{\add{y}{z}}$

$\power{x}{\power{y}{\add{z}{w}}}$

$\subtract{\power{x}{\product{\power{y}{\add{z}{w}}}{\subtract{z}{w}}}}{\subtract{d}{e}}$

\nopagenumbers
\bye

How I wrote it first: (I had something more general in mind for the branch contents, but in the end they differ only in the presence of ( and ))

\catcode`@ 11
\long\def\@firstoftwo #1#2{#1}
\long\def\@secondoftwo #1#2{#2}

\def\power #1#2{% 
\ifnum\p>3 \expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi
{{({\def\p{4}#1}^{\def\p{0}#2})}}{{\def\p{4}#1}^{\def\p{0}#2}}}

\def\product#1#2{% 
\ifnum\p>2 \expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi
{{(\def\p{2}#1#2)}}{{\def\p{2}#1#2}}}

\def\add#1#2{%
\ifnum\p>1 \expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi
{{(\def\p{0}#1+#2)}}{{\def\p{0}#1+#2}}}

\def\subtract#1#2{%
\ifnum\p>0 \expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi
{{(\def\p{0}#1-\def\p{2}#2)}}{{\def\p{0}#1-\def\p{2}#2}}}

\catcode`@ 12

parentheses removal

share|improve this answer
    
Am I right in thinking the only change from David Carlisle's answer is that the numerical parameters have been changed? –  Mohan Feb 20 at 17:13
1  
it's a bit more for \subtract (\p is changed at two locations and goes up to multiplication in a way) and also \power (the first \p changes in the opposite direction). As a result (((a-b)-c)-d) and a+(b-c) are correctly stripped of parentheses. –  jfbu Feb 20 at 17:22
1  
and $\power{\power{\power{x}{y}}{z}}{t}$ is correctly handled to output ((x^y)^z)^t. –  jfbu Feb 20 at 17:29

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.