3 * Implementation of GiNaC's light-weight expression handles. */
6 * GiNaC Copyright (C) 1999-2003 Johannes Gutenberg University Mainz, Germany
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
33 #include "relational.h"
34 #include "input_lexer.h"
46 // non-virtual functions in this class
51 /** Print expression to stream. The formatting of the output is determined
52 * by the kind of print_context object that is passed. Possible formattings
53 * include ginsh-parsable output (the default), tree-like output for
54 * debugging, and C++ source.
55 * @see print_context */
56 void ex::print(const print_context & c, unsigned level) const
61 /** Little wrapper arount print to be called within a debugger. */
62 void ex::dbgprint() const
67 /** Little wrapper arount printtree to be called within a debugger. */
68 void ex::dbgprinttree() const
73 ex ex::expand(unsigned options) const
75 if (options == 0 && (bp->flags & status_flags::expanded)) // The "expanded" flag only covers the standard options; someone might want to re-expand with different options
78 return bp->expand(options);
81 /** Compute partial derivative of an expression.
83 * @param s symbol by which the expression is derived
84 * @param nth order of derivative (default 1)
85 * @return partial derivative as a new expression */
86 ex ex::diff(const symbol & s, unsigned nth) const
91 return bp->diff(s, nth);
94 /** Check whether expression matches a specified pattern. */
95 bool ex::match(const ex & pattern) const
98 return bp->match(pattern, repl_lst);
101 /** Find all occurrences of a pattern. The found matches are appended to
102 * the "found" list. If the expression itself matches the pattern, the
103 * children are not further examined. This function returns true when any
104 * matches were found. */
105 bool ex::find(const ex & pattern, lst & found) const
107 if (match(pattern)) {
113 bool any_found = false;
114 for (size_t i=0; i<nops(); i++)
115 if (op(i).find(pattern, found))
120 /** Substitute objects in an expression (syntactic substitution) and return
121 * the result as a new expression. */
122 ex ex::subs(const lst & ls, const lst & lr, unsigned options) const
124 GINAC_ASSERT(ls.nops() == lr.nops());
126 // Convert the lists to a map
128 for (lst::const_iterator its = ls.begin(), itr = lr.begin(); its != ls.end(); ++its, ++itr) {
129 m.insert(std::make_pair(*its, *itr));
131 // Search for products and powers in the expressions to be substituted
132 // (for an optimization in expairseq::subs())
133 if (is_exactly_a<mul>(*its) || is_exactly_a<power>(*its))
134 options |= subs_options::pattern_is_product;
136 if (!(options & subs_options::pattern_is_product))
137 options |= subs_options::pattern_is_not_product;
139 return bp->subs(m, options);
142 /** Substitute objects in an expression (syntactic substitution) and return
143 * the result as a new expression. There are two valid types of
144 * replacement arguments: 1) a relational like object==ex and 2) a list of
145 * relationals lst(object1==ex1,object2==ex2,...). */
146 ex ex::subs(const ex & e, unsigned options) const
148 if (e.info(info_flags::relation_equal)) {
150 const ex & s = e.op(0);
151 m.insert(std::make_pair(s, e.op(1)));
152 if (is_exactly_a<mul>(s) || is_exactly_a<power>(s))
153 options |= subs_options::pattern_is_product;
155 options |= subs_options::pattern_is_not_product;
156 return bp->subs(m, options);
157 } else if (!e.info(info_flags::list))
158 throw(std::invalid_argument("basic::subs(ex): argument must be a list"));
160 // Convert the list to a map
162 GINAC_ASSERT(is_a<lst>(e));
163 for (lst::const_iterator it = ex_to<lst>(e).begin(); it != ex_to<lst>(e).end(); ++it) {
165 if (!r.info(info_flags::relation_equal))
166 throw(std::invalid_argument("basic::subs(ex): argument must be a list of equations"));
167 const ex & s = r.op(0);
168 m.insert(std::make_pair(s, r.op(1)));
170 // Search for products and powers in the expressions to be substituted
171 // (for an optimization in expairseq::subs())
172 if (is_exactly_a<mul>(s) || is_exactly_a<power>(s))
173 options |= subs_options::pattern_is_product;
175 if (!(options & subs_options::pattern_is_product))
176 options |= subs_options::pattern_is_not_product;
178 return bp->subs(m, options);
181 /** Traverse expression tree with given visitor, preorder traversal. */
182 void ex::traverse_preorder(visitor & v) const
187 for (size_t i = 0; i < n; ++i)
188 op(i).traverse_preorder(v);
191 /** Traverse expression tree with given visitor, postorder traversal. */
192 void ex::traverse_postorder(visitor & v) const
195 for (size_t i = 0; i < n; ++i)
196 op(i).traverse_postorder(v);
201 /** Return modifyable operand/member at position i. */
202 ex & ex::let_op(size_t i)
205 return bp->let_op(i);
208 ex & ex::operator[](const ex & index)
214 ex & ex::operator[](size_t i)
220 /** Left hand side of relational expression. */
223 if (!is_a<relational>(*this))
224 throw std::runtime_error("ex::lhs(): not a relation");
228 /** Right hand side of relational expression. */
231 if (!is_a<relational>(*this))
232 throw std::runtime_error("ex::rhs(): not a relation");
238 /** Make this ex writable (if more than one ex handle the same basic) by
239 * unlinking the object and creating an unshared copy of it. */
240 void ex::makewriteable()
242 GINAC_ASSERT(bp->flags & status_flags::dynallocated);
244 GINAC_ASSERT(bp->get_refcount() == 1);
247 /** Share equal objects between expressions.
248 * @see ex::compare(const basic &) */
249 void ex::share(const ex & other) const
251 if ((bp->flags | other.bp->flags) & status_flags::not_shareable)
254 if (bp->get_refcount() <= other.bp->get_refcount())
260 /** Helper function for the ex-from-basic constructor. This is where GiNaC's
261 * automatic evaluator and memory management are implemented.
262 * @see ex::ex(const basic &) */
263 ptr<basic> ex::construct_from_basic(const basic & other)
265 if (!(other.flags & status_flags::evaluated)) {
267 // The object is not yet evaluated, so call eval() to evaluate
268 // the top level. This will return either
269 // a) the original object with status_flags::evaluated set (when the
270 // eval() implementation calls hold())
272 // b) a different expression.
274 // eval() returns an ex, not a basic&, so this will go through
275 // construct_from_basic() a second time. In case a) we end up in
276 // the "else" branch below. In case b) we end up here again and
277 // apply eval() once more. The recursion stops when eval() calls
278 // hold() or returns an object that already has its "evaluated"
279 // flag set, such as a symbol or a numeric.
280 const ex & tmpex = other.eval(1);
282 // Eventually, the eval() recursion goes through the "else" branch
283 // below, which assures that the object pointed to by tmpex.bp is
284 // allocated on the heap (either it was already on the heap or it
285 // is a heap-allocated duplicate of another object).
286 GINAC_ASSERT(tmpex.bp->flags & status_flags::dynallocated);
288 // If the original object is not referenced but heap-allocated,
289 // it means that eval() hit case b) above. The original object is
290 // no longer needed (it evaluated into something different), so we
291 // delete it (because nobody else will).
292 if ((other.get_refcount() == 0) && (other.flags & status_flags::dynallocated))
293 delete &other; // yes, you can apply delete to a const pointer
295 // We can't return a basic& here because the tmpex is destroyed as
296 // soon as we leave the function, which would deallocate the
302 // The easy case: making an "ex" out of an evaluated object.
303 if (other.flags & status_flags::dynallocated) {
305 // The object is already heap-allocated, so we can just make
306 // another reference to it.
307 return ptr<basic>(const_cast<basic &>(other));
311 // The object is not heap-allocated, so we create a duplicate
313 basic *bp = other.duplicate();
314 bp->setflag(status_flags::dynallocated);
315 GINAC_ASSERT(bp->get_refcount() == 0);
321 basic & ex::construct_from_int(int i)
323 switch (i) { // prefer flyweights over new objects
325 return const_cast<numeric &>(_num_12);
327 return const_cast<numeric &>(_num_11);
329 return const_cast<numeric &>(_num_10);
331 return const_cast<numeric &>(_num_9);
333 return const_cast<numeric &>(_num_8);
335 return const_cast<numeric &>(_num_7);
337 return const_cast<numeric &>(_num_6);
339 return const_cast<numeric &>(_num_5);
341 return const_cast<numeric &>(_num_4);
343 return const_cast<numeric &>(_num_3);
345 return const_cast<numeric &>(_num_2);
347 return const_cast<numeric &>(_num_1);
349 return const_cast<numeric &>(_num0);
351 return const_cast<numeric &>(_num1);
353 return const_cast<numeric &>(_num2);
355 return const_cast<numeric &>(_num3);
357 return const_cast<numeric &>(_num4);
359 return const_cast<numeric &>(_num5);
361 return const_cast<numeric &>(_num6);
363 return const_cast<numeric &>(_num7);
365 return const_cast<numeric &>(_num8);
367 return const_cast<numeric &>(_num9);
369 return const_cast<numeric &>(_num10);
371 return const_cast<numeric &>(_num11);
373 return const_cast<numeric &>(_num12);
375 basic *bp = new numeric(i);
376 bp->setflag(status_flags::dynallocated);
377 GINAC_ASSERT(bp->get_refcount() == 0);
382 basic & ex::construct_from_uint(unsigned int i)
384 switch (i) { // prefer flyweights over new objects
386 return const_cast<numeric &>(_num0);
388 return const_cast<numeric &>(_num1);
390 return const_cast<numeric &>(_num2);
392 return const_cast<numeric &>(_num3);
394 return const_cast<numeric &>(_num4);
396 return const_cast<numeric &>(_num5);
398 return const_cast<numeric &>(_num6);
400 return const_cast<numeric &>(_num7);
402 return const_cast<numeric &>(_num8);
404 return const_cast<numeric &>(_num9);
406 return const_cast<numeric &>(_num10);
408 return const_cast<numeric &>(_num11);
410 return const_cast<numeric &>(_num12);
412 basic *bp = new numeric(i);
413 bp->setflag(status_flags::dynallocated);
414 GINAC_ASSERT(bp->get_refcount() == 0);
419 basic & ex::construct_from_long(long i)
421 switch (i) { // prefer flyweights over new objects
423 return const_cast<numeric &>(_num_12);
425 return const_cast<numeric &>(_num_11);
427 return const_cast<numeric &>(_num_10);
429 return const_cast<numeric &>(_num_9);
431 return const_cast<numeric &>(_num_8);
433 return const_cast<numeric &>(_num_7);
435 return const_cast<numeric &>(_num_6);
437 return const_cast<numeric &>(_num_5);
439 return const_cast<numeric &>(_num_4);
441 return const_cast<numeric &>(_num_3);
443 return const_cast<numeric &>(_num_2);
445 return const_cast<numeric &>(_num_1);
447 return const_cast<numeric &>(_num0);
449 return const_cast<numeric &>(_num1);
451 return const_cast<numeric &>(_num2);
453 return const_cast<numeric &>(_num3);
455 return const_cast<numeric &>(_num4);
457 return const_cast<numeric &>(_num5);
459 return const_cast<numeric &>(_num6);
461 return const_cast<numeric &>(_num7);
463 return const_cast<numeric &>(_num8);
465 return const_cast<numeric &>(_num9);
467 return const_cast<numeric &>(_num10);
469 return const_cast<numeric &>(_num11);
471 return const_cast<numeric &>(_num12);
473 basic *bp = new numeric(i);
474 bp->setflag(status_flags::dynallocated);
475 GINAC_ASSERT(bp->get_refcount() == 0);
480 basic & ex::construct_from_ulong(unsigned long i)
482 switch (i) { // prefer flyweights over new objects
484 return const_cast<numeric &>(_num0);
486 return const_cast<numeric &>(_num1);
488 return const_cast<numeric &>(_num2);
490 return const_cast<numeric &>(_num3);
492 return const_cast<numeric &>(_num4);
494 return const_cast<numeric &>(_num5);
496 return const_cast<numeric &>(_num6);
498 return const_cast<numeric &>(_num7);
500 return const_cast<numeric &>(_num8);
502 return const_cast<numeric &>(_num9);
504 return const_cast<numeric &>(_num10);
506 return const_cast<numeric &>(_num11);
508 return const_cast<numeric &>(_num12);
510 basic *bp = new numeric(i);
511 bp->setflag(status_flags::dynallocated);
512 GINAC_ASSERT(bp->get_refcount() == 0);
517 basic & ex::construct_from_double(double d)
519 basic *bp = new numeric(d);
520 bp->setflag(status_flags::dynallocated);
521 GINAC_ASSERT(bp->get_refcount() == 0);
525 ptr<basic> ex::construct_from_string_and_lst(const std::string &s, const ex &l)
528 set_lexer_symbols(l);
529 ginac_yyrestart(NULL);
531 throw (std::runtime_error(get_parser_error()));
537 // static member variables
543 // functions which are not member functions