]> www.ginac.de Git - ginac.git/blobdiff - ginac/symbol.cpp
- The status_flags::expanded is now used on some occasions.
[ginac.git] / ginac / symbol.cpp
index 2d42b5af8047055e5d005df9431258de7046e0fd..7dd1c5228107dc22c5a30f8309cfd940d2cc505d 100644 (file)
@@ -3,7 +3,7 @@
  *  Implementation of GiNaC's symbolic objects. */
 
 /*
- *  GiNaC Copyright (C) 1999 Johannes Gutenberg University Mainz, Germany
+ *  GiNaC Copyright (C) 1999-2000 Johannes Gutenberg University Mainz, Germany
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
 
 #include "symbol.h"
 #include "lst.h"
-#include "utils.h"
 #include "idx.h"
+#include "archive.h"
 #include "debugmsg.h"
+#include "utils.h"
 
+#ifndef NO_NAMESPACE_GINAC
 namespace GiNaC {
+#endif // ndef NO_NAMESPACE_GINAC
+
+GINAC_IMPLEMENT_REGISTERED_CLASS(symbol, basic)
 
 //////////
 // default constructor, destructor, copy constructor assignment operator and helpers
 //////////
 
-symbol::symbol() : basic(TINFO_symbol)
+symbol::symbol() : inherited(TINFO_symbol)
 {
-    debugmsg("symbol default constructor",LOGLEVEL_CONSTRUCT);
-    serial=next_serial++;
-    name=autoname_prefix()+ToString(serial);
-    asexinfop=new assigned_ex_info;
+    debugmsg("symbol default constructor", LOGLEVEL_CONSTRUCT);
+    serial = next_serial++;
+    name = autoname_prefix()+ToString(serial);
+    asexinfop = new assigned_ex_info;
     setflag(status_flags::evaluated);
 }
 
 symbol::~symbol()
 {
-    debugmsg("symbol destructor",LOGLEVEL_DESTRUCT);
+    debugmsg("symbol destructor", LOGLEVEL_DESTRUCT);
     destroy(0);
 }
 
-symbol::symbol(symbol const & other)
+symbol::symbol(const symbol & other)
 {
-    debugmsg("symbol copy constructor",LOGLEVEL_CONSTRUCT);
+    debugmsg("symbol copy constructor", LOGLEVEL_CONSTRUCT);
     copy(other);
 }
 
-void symbol::copy(symbol const & other)
+void symbol::copy(const symbol & other)
 {
-    basic::copy(other);
-    name=other.name;
-    serial=other.serial;
-    asexinfop=other.asexinfop;
+    inherited::copy(other);
+    name = other.name;
+    serial = other.serial;
+    asexinfop = other.asexinfop;
     ++asexinfop->refcount;
 }
 
@@ -71,7 +76,7 @@ void symbol::destroy(bool call_parent)
         delete asexinfop;
     }
     if (call_parent) {
-        basic::destroy(call_parent);
+        inherited::destroy(call_parent);
     }
 }
 
@@ -87,34 +92,102 @@ void symbol::destroy(bool call_parent)
 
 // public
 
-symbol::symbol(string const & initname) : basic(TINFO_symbol)
+symbol::symbol(const string & initname) : inherited(TINFO_symbol)
+{
+    debugmsg("symbol constructor from string", LOGLEVEL_CONSTRUCT);
+    name = initname;
+    serial = next_serial++;
+    asexinfop = new assigned_ex_info;
+    setflag(status_flags::evaluated);
+}
+
+//////////
+// archiving
+//////////
+
+/** Construct object from archive_node. */
+symbol::symbol(const archive_node &n, const lst &sym_lst) : inherited(n, sym_lst)
 {
-    debugmsg("symbol constructor from string",LOGLEVEL_CONSTRUCT);
-    name=initname;
-    serial=next_serial++;
-    asexinfop=new assigned_ex_info;
+    debugmsg("symbol constructor from archive_node", LOGLEVEL_CONSTRUCT);
+    serial = next_serial++;
+    if (!(n.find_string("name", name)))
+        name = autoname_prefix() + ToString(serial);
+    asexinfop = new assigned_ex_info;
     setflag(status_flags::evaluated);
 }
 
+/** Unarchive the object. */
+ex symbol::unarchive(const archive_node &n, const lst &sym_lst)
+{
+    ex s = (new symbol(n, sym_lst))->setflag(status_flags::dynallocated);
+
+    // If symbol is in sym_lst, return the existing symbol
+    for (unsigned i=0; i<sym_lst.nops(); i++) {
+        if (is_ex_of_type(sym_lst.op(i), symbol) && (ex_to_symbol(sym_lst.op(i)).name == ex_to_symbol(s).name))
+            return sym_lst.op(i);
+    }
+    return s;
+}
+
+/** Archive the object. */
+void symbol::archive(archive_node &n) const
+{
+    inherited::archive(n);
+    n.add_string("name", name);
+}
+
 //////////
 // functions overriding virtual functions from bases classes
 //////////
 
 // public
 
-basic * symbol::duplicate() const
+basic *symbol::duplicate() const
 {
-    debugmsg("symbol duplicate",LOGLEVEL_DUPLICATE);
+    debugmsg("symbol duplicate", LOGLEVEL_DUPLICATE);
     return new symbol(*this);
 }
 
+void symbol::print(ostream & os, unsigned upper_precedence) const
+{
+    debugmsg("symbol print",LOGLEVEL_PRINT);
+    os << name;
+}
+
+void symbol::printraw(ostream & os) const
+{
+    debugmsg("symbol printraw",LOGLEVEL_PRINT);
+    os << "symbol(" << "name=" << name << ",serial=" << serial
+       << ",hash=" << hashvalue << ",flags=" << flags << ")";
+}
+
+void symbol::printtree(ostream & os, unsigned indent) const
+{
+    debugmsg("symbol printtree",LOGLEVEL_PRINT);
+    os << string(indent,' ') << name << " (symbol): "
+       << "serial=" << serial
+       << ", hash=" << hashvalue << " (0x" << hex << hashvalue << dec << ")"
+       << ", flags=" << flags << endl;
+}
+
+void symbol::printcsrc(ostream & os, unsigned type, unsigned upper_precedence) const
+{
+    debugmsg("symbol print csrc", LOGLEVEL_PRINT);
+    os << name;
+}
+
 bool symbol::info(unsigned inf) const
 {
     if (inf==info_flags::symbol) return true;
-    if (inf==info_flags::polynomial || inf==info_flags::integer_polynomial || inf==info_flags::rational_polynomial || inf==info_flags::rational_function) {
+    if (inf==info_flags::polynomial ||
+        inf==info_flags::integer_polynomial ||
+        inf==info_flags::cinteger_polynomial ||
+        inf==info_flags::rational_polynomial ||
+        inf==info_flags::crational_polynomial ||
+        inf==info_flags::rational_function) {
         return true;
     } else {
-        return basic::info(inf);
+        return inherited::info(inf);
     }
 }
 
@@ -123,28 +196,28 @@ ex symbol::expand(unsigned options) const
     return this->hold();
 }
 
-bool symbol::has(ex const & other) const
+bool symbol::has(const ex & other) const
 {
     if (is_equal(*other.bp)) return true;
     return false;
 }
 
-int symbol::degree(symbol const & s) const
+int symbol::degree(const symbol & s) const
 {
     return compare_same_type(s)==0 ? 1 : 0;
 }
 
-int symbol::ldegree(symbol const & s) const
+int symbol::ldegree(const symbol & s) const
 {
     return compare_same_type(s)==0 ? 1 : 0;
 }
 
-ex symbol::coeff(symbol const & s, int const n) const
+ex symbol::coeff(const symbol & s, int n) const
 {
     if (compare_same_type(s)==0) {
-        return n==1 ? exONE() : exZERO();
+        return n==1 ? _ex1() : _ex0();
     } else {
-        return n==0 ? *this : exZERO();
+        return n==0 ? *this : _ex0();
     }
 }
 
@@ -166,17 +239,17 @@ ex symbol::eval(int level) const
     }
 }
 
-ex symbol::subs(lst const & ls, lst const & lr) const
+ex symbol::subs(const lst & ls, const lst & lr) const
 {
-    ASSERT(ls.nops()==lr.nops());
-#ifdef DOASSERT
-    for (int i=0; i<ls.nops(); i++) {
-        ASSERT(is_ex_exactly_of_type(ls.op(i),symbol)||
+    GINAC_ASSERT(ls.nops()==lr.nops());
+#ifdef DO_GINAC_ASSERT
+    for (unsigned i=0; i<ls.nops(); i++) {
+        GINAC_ASSERT(is_ex_exactly_of_type(ls.op(i),symbol)||
                is_ex_of_type(ls.op(i),idx));
     }
-#endif // def DOASSERT
+#endif // def DO_GINAC_ASSERT
 
-    for (int i=0; i<ls.nops(); i++) {
+    for (unsigned i=0; i<ls.nops(); i++) {
         if (is_ex_exactly_of_type(ls.op(i),symbol)) {
             if (compare_same_type(ex_to_symbol(ls.op(i)))==0) return lr.op(i);
         }
@@ -186,17 +259,30 @@ ex symbol::subs(lst const & ls, lst const & lr) const
 
 // protected
 
-int symbol::compare_same_type(basic const & other) const
+/** Implementation of ex::diff() for single differentiation of a symbol.
+ *  It returns 1 or 0.
+ *
+ *  @see ex::diff */
+ex symbol::derivative(const symbol & s) const
+{
+    if (compare_same_type(s)) {
+        return _ex0();
+    } else {
+        return _ex1();
+    }
+}
+
+int symbol::compare_same_type(const basic & other) const
 {
-    ASSERT(is_of_type(other,symbol));
+    GINAC_ASSERT(is_of_type(other,symbol));
     const symbol *o = static_cast<const symbol *>(&other);
     if (serial==o->serial) return 0;
     return serial < o->serial ? -1 : 1;
 }
 
-bool symbol::is_equal_same_type(basic const & other) const
+bool symbol::is_equal_same_type(const basic & other) const
 {
-    ASSERT(is_of_type(other,symbol));
+    GINAC_ASSERT(is_of_type(other,symbol));
     const symbol *o = static_cast<const symbol *>(&other);
     return serial==o->serial;
 }
@@ -231,7 +317,7 @@ unsigned symbol::calchash(void) const
 
 // public
 
-void symbol::assign(ex const & value)
+void symbol::assign(const ex & value)
 {
     asexinfop->is_assigned=1;
     asexinfop->assigned_expression=value;
@@ -242,7 +328,7 @@ void symbol::unassign(void)
 {
     if (asexinfop->is_assigned) {
         asexinfop->is_assigned=0;
-        asexinfop->assigned_expression=exZERO();
+        asexinfop->assigned_expression=_ex0();
     }
     setflag(status_flags::evaluated);
 }
@@ -270,7 +356,7 @@ unsigned symbol::next_serial=0;
 //////////
 
 const symbol some_symbol;
-type_info const & typeid_symbol=typeid(some_symbol);
+const type_info & typeid_symbol=typeid(some_symbol);
 
 //////////
 // subclass assigned_ex_info
@@ -281,4 +367,6 @@ symbol::assigned_ex_info::assigned_ex_info(void) : is_assigned(0), refcount(1)
 {
 }
 
+#ifndef NO_NAMESPACE_GINAC
 } // namespace GiNaC
+#endif // ndef NO_NAMESPACE_GINAC