1 /**
2  * @file    L3FormulaFormatter.h
3  * @brief   Formats an L3 AST formula tree as an SBML formula string.
4  * @author  Lucian Smith
5  *
6  * @if conly
7  * This file contains the SBML_formulaToL3String() and SBML_formulaToL3StringWithSettings()
8  * functions, both associated with the ASTNode_t structure.
9  * @endif
10  *
11  * <!--------------------------------------------------------------------------
12  * This file is part of libSBML.  Please visit http://sbml.org for more
13  * information about SBML, and the latest version of libSBML.
14  *
15  * Copyright (C) 2020 jointly by the following organizations:
16  *     1. California Institute of Technology, Pasadena, CA, USA
17  *     2. University of Heidelberg, Heidelberg, Germany
18  *     3. University College London, London, UK
19  *
20  * Copyright (C) 2019 jointly by the following organizations:
21  *     1. California Institute of Technology, Pasadena, CA, USA
22  *     2. University of Heidelberg, Heidelberg, Germany
23  *
24  * Copyright (C) 2013-2018 jointly by the following organizations:
25  *     1. California Institute of Technology, Pasadena, CA, USA
26  *     2. EMBL European Bioinformatics Institute (EMBL-EBI), Hinxton, UK
27  *     3. University of Heidelberg, Heidelberg, Germany
28  *
29  * Copyright (C) 2009-2013 jointly by the following organizations:
30  *     1. California Institute of Technology, Pasadena, CA, USA
31  *     2. EMBL European Bioinformatics Institute (EMBL-EBI), Hinxton, UK
32  *
33  * Copyright (C) 2006-2008 by the California Institute of Technology,
34  *     Pasadena, CA, USA
35  *
36  * Copyright (C) 2002-2005 jointly by the following organizations:
37  *     1. California Institute of Technology, Pasadena, CA, USA
38  *     2. Japan Science and Technology Agency, Japan
39  *
40  * This library is free software; you can redistribute it and/or modify it
41  * under the terms of the GNU Lesser General Public License as published by
42  * the Free Software Foundation.  A copy of the license agreement is provided
43  * in the file named "LICENSE.txt" included with this software distribution and
44  * also available online as http://sbml.org/software/libsbml/license.html
45  * ---------------------------------------------------------------------- -->*/
46 
47 #ifndef L3FormulaFormatter_h
48 #define L3FormulaFormatter_h
49 
50 
51 #include <sbml/common/extern.h>
52 #include <sbml/util/StringBuffer.h>
53 
54 #include <sbml/math/ASTNode.h>
55 
56 LIBSBML_CPP_NAMESPACE_BEGIN
57 BEGIN_C_DECLS
58 
59 
60 /**
61  * Converts an AST to a string representation of a formula using a syntax
62  * derived from SBML Level&nbsp;1, but extended to include elements from
63  * SBML Level&nbsp;2 and SBML Level&nbsp;3.
64  *
65  * @copydetails doc_summary_of_string_math_l3
66  *
67  * @param tree the AST to be converted.
68  *
69  * @return the formula from the given AST as text string, with a syntax
70  * oriented towards the capabilities defined in SBML Level&nbsp;3.  The
71  * caller owns the returned string and is responsible for freeing it when it
72  * is no longer needed.  If @p tree is a null pointer, then a null pointer is
73  * returned.
74  *
75  * @see @sbmlfunction{formulaToL3StringWithSettings, ASTNode\, L3ParserSettings}
76  * @see @sbmlfunction{formulaToString, ASTNode}
77  * @see @sbmlfunction{parseL3FormulaWithSettings, String\, L3ParserSettings}
78  * @see @sbmlfunction{parseL3FormulaWithModel, String\, Model}
79  * @see @sbmlfunction{parseFormula, String}
80  * @see L3ParserSettings
81  * @see @sbmlfunction{getDefaultL3ParserSettings,}
82  * @see @sbmlfunction{getLastParseL3Error,}
83  *
84  * @if conly
85  * @memberof ASTNode_t
86  * @endif
87  */
88 LIBSBML_EXTERN
89 char *
90 SBML_formulaToL3String (const ASTNode_t *tree);
91 
92 
93 /**
94  * Converts an AST to a text string representation of a formula, using
95  * specific formatter settings.
96  *
97  * This function behaves identically to @sbmlfunction{formulaToL3String,
98  * ASTNode} but its behavior is controlled by two fields in the @p
99  * settings object, namely:
100  *
101  * @li <em>parseunits</em> ("parse units"): If this field in the @p settings
102  *     object is set to <code>true</code> (the default), the function will
103  *     write out the units of any numerical ASTNodes that have them,
104  *     producing (for example) &quot;<code>3 mL</code>&quot;,
105  *     &quot;<code>(3/4) m</code>&quot;, or &quot;<code>5.5e-10
106  *     M</code>&quot;.  If this is set to <code>false</code>, this function
107  *     will only write out the number itself (&quot;<code>3</code>&quot;,
108  *     &quot;<code>(3/4)</code>&quot;, and &quot;<code>5.5e-10</code>&quot;,
109  *     in the previous examples).
110  * @li <em>collapseminus</em> ("collapse minus"): If this field in the @p
111  *     settings object is set to <code>false</code> (the default), the
112  *     function will write out explicitly any doubly-nested unary minus
113  *     ASTNodes, producing (for example) &quot;<code>- -x</code>&quot; or
114  *     even &quot;<code>- - - - -3.1</code>&quot;.  If this is set to
115  *     <code>true</code>, the function will collapse the nodes before
116  *     producing the infix form, producing &quot;<code>x</code>&quot; and
117  *     &quot;<code>-3.1</code>&quot; in the previous examples.
118  *
119  * All the other settings of the L3ParserSettings object passed in as @p
120  * settings will be ignored for the purposes of this function: the
121  * <em>parselog</em> ("parse log") setting is ignored so that
122  * &quot;<code>log10(x)</code>&quot;, &quot;<code>ln(x)</code>&quot;, and
123  * &quot;<code>log(x, y)</code>&quot; are always produced; the
124  * <em>avocsymbol</em> ("Avogadro csymbol") is irrelevant to the behavior
125  * of this function; and nothing in the Model object set via the
126  * <em>model</em> setting is used.
127  *
128  * @param tree the AST to be converted.
129 
130  * @param settings the L3ParserSettings object used to modify the behavior of
131  * this function.
132  *
133  * @return the formula from the given AST as text string, with a syntax
134  * oriented towards the capabilities defined in SBML Level&nbsp;3.  The
135  * caller owns the returned string and is responsible for freeing it when it
136  * is no longer needed.  If @p tree is a null pointer, then a null pointer is
137  * returned.
138  *
139  * @see @sbmlfunction{formulaToL3String, ASTNode}
140  * @see @sbmlfunction{formulaToString, ASTNode}
141  * @see @sbmlfunction{parseL3FormulaWithSettings, String\, L3ParserSettings}
142  * @see @sbmlfunction{parseL3FormulaWithModel, String\, Model}
143  * @see @sbmlfunction{parseFormula, String}
144  * @see L3ParserSettings
145  * @see @sbmlfunction{getDefaultL3ParserSettings,}
146  * @see @sbmlfunction{getLastParseL3Error,}
147  *
148  * @if conly
149  * @memberof ASTNode_t
150  * @endif
151  */
152 LIBSBML_EXTERN
153 char *
154 SBML_formulaToL3StringWithSettings (const ASTNode_t *tree, const L3ParserSettings_t *settings);
155 
156 
157 /** @cond doxygenLibsbmlInternal */
158 
159 #ifndef SWIG
160 
161 
162 /**
163  * @return @c 1 (true) if the given ASTNode_t is to be
164  * formatted as a function.
165  */
166 int
167 L3FormulaFormatter_isFunction (const ASTNode_t *node, const L3ParserSettings_t *settings);
168 
169 
170 /**
171  * @return @c 1 (true) if the given child ASTNode_t should be grouped
172  * (with parenthesis), @c 0 (false) otherwise.
173  *
174  * A node should be group if it is not an argument to a function and
175  * either:
176  *
177  *   - The parent node has higher precedence than the child, or
178  *
179  *   - If parent node has equal precedence with the child and the child is
180  *     to the right.  In this case, operator associativity and right-most
181  *     AST derivation enforce the grouping.
182  */
183 int
184 L3FormulaFormatter_isGrouped (const ASTNode_t *parent, const ASTNode_t *child, const L3ParserSettings_t *settings);
185 
186 
187 /**
188  * Formats the given ASTNode_t as an SBML L1 token and appends the result to
189  * the given StringBuffer_t.
190  */
191 void
192 L3FormulaFormatter_format (StringBuffer_t *sb, const ASTNode_t *node, const L3ParserSettings_t *settings);
193 
194 
195 /**
196  * Formats the given ASTNode_t as an SBML L1 function name and appends the
197  * result to the given StringBuffer_t.
198  */
199 void
200 L3FormulaFormatter_formatFunction (StringBuffer_t *sb, const ASTNode_t *node, const L3ParserSettings_t *settings);
201 
202 
203 /**
204  * Formats the given ASTNode_t as an SBML L3 operator and appends the result
205  * to the given StringBuffer_t.
206  */
207 void
208 L3FormulaFormatter_formatOperator (StringBuffer_t *sb, const ASTNode_t *node);
209 
210 /**
211  * Formats the given ASTNode_t as a rational number and appends the result to
212  * the given StringBuffer_t.  This amounts to:
213  *
214  *   "(numerator/denominator)"
215  *
216  * If the ASTNode_t has defined units, and the settings object is set to parse units, this function will append
217  * a string with that unit name.
218  */
219 void
220 L3FormulaFormatter_formatRational (StringBuffer_t *sb, const ASTNode_t *node, const L3ParserSettings_t *settings);
221 
222 
223 /**
224  * Formats the given ASTNode_t as a real number and appends the result to
225  * the given StringBuffer_t.
226  *
227  * If the ASTNode_t has defined units, and the settings object is set to parse units, this function will append
228  * a string with that unit name.
229  */
230 void
231 L3FormulaFormatter_formatReal (StringBuffer_t *sb, const ASTNode_t *node, const L3ParserSettings_t *settings);
232 
233 
234 /**
235  * Formats the given logical or relational ASTNode_t as an infix
236  * internal operator and appends the result to the given StringBuffer_t.
237  */
238 void
239 L3FormulaFormatter_formatLogicalRelational(StringBuffer_t *sb, const ASTNode_t *node);
240 
241 /**
242  * Visits the given ASTNode_t node.  This function is really just a
243  * dispatcher to either SBML_formulaToL3String_visitFunction() or
244  * SBML_formulaToL3String_visitOther().
245  */
246 void
247 L3FormulaFormatter_visit ( const ASTNode_t *parent,
248                            const ASTNode_t *node,
249                            StringBuffer_t  *sb,
250                            const L3ParserSettings_t *settings );
251 
252 
253 /**
254  * Visits the given ASTNode_t as a function.  For this node only the
255  * traversal is preorder.
256  */
257 void
258 L3FormulaFormatter_visitFunction ( const ASTNode_t *parent,
259                                    const ASTNode_t *node,
260                                    StringBuffer_t  *sb,
261                                    const L3ParserSettings_t *settings );
262 
263 
264 /**
265  * Visits the given ASTNode_t as the function "log(10, x)" and in doing so,
266  * formats it as "log10(x)" (where x is any subexpression).
267  */
268 void
269 L3FormulaFormatter_visitLog10 ( const ASTNode_t *parent,
270                                 const ASTNode_t *node,
271                                 StringBuffer_t  *sb,
272                                 const L3ParserSettings_t *settings );
273 
274 
275 /**
276  * Visits the given ASTNode_t as the function "root(2, x)" and in doing so,
277  * formats it as "sqrt(x)" (where x is any subexpression).
278  */
279 void
280 L3FormulaFormatter_visitSqrt ( const ASTNode_t *parent,
281                                const ASTNode_t *node,
282                                StringBuffer_t  *sb,
283                                const L3ParserSettings_t *settings );
284 
285 
286 /**
287  * Visits the given ASTNode_t as a unary minus.  For this node only the
288  * traversal is preorder.
289  */
290 void
291 L3FormulaFormatter_visitUMinus ( const ASTNode_t *parent,
292                                  const ASTNode_t *node,
293                                  StringBuffer_t  *sb,
294                                  const L3ParserSettings_t *settings );
295 
296 
297 /**
298  * Visits the given ASTNode_t as a unary not.
299  */
300 void
301 L3FormulaFormatter_visitUNot ( const ASTNode_t *parent,
302                                const ASTNode_t *node,
303                                StringBuffer_t  *sb,
304                                const L3ParserSettings_t *settings );
305 /**
306  * Visits the given ASTNode_t, translating it from the complicated
307  * piecewise function to the much simpler 'x % y' form.
308  */
309 void
310 L3FormulaFormatter_visitModulo ( const ASTNode_t *parent,
311                                  const ASTNode_t *node,
312                                  StringBuffer_t  *sb,
313                                  const L3ParserSettings_t *settings );
314 
315 /**
316  * Visits the given ASTNode_t and continues the inorder traversal.
317  */
318 void
319 L3FormulaFormatter_visitOther ( const ASTNode_t *parent,
320                                 const ASTNode_t *node,
321                                 StringBuffer_t  *sb,
322                                 const L3ParserSettings_t *settings );
323 
324 
325 #endif  /* !SWIG */
326 
327 END_C_DECLS
328 LIBSBML_CPP_NAMESPACE_END
329 /** @endcond */
330 
331 #endif  /* L3FormulaFormatter_h */
332 
333