]> 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 94c008c2b15691b1610decee66999af2b4a61ea6..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_GINAC_NAMESPACE
+#ifndef NO_NAMESPACE_GINAC
 namespace GiNaC {
-#endif // ndef NO_GINAC_NAMESPACE
+#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;
 }
 
@@ -73,7 +76,7 @@ void symbol::destroy(bool call_parent)
         delete asexinfop;
     }
     if (call_parent) {
-        basic::destroy(call_parent);
+        inherited::destroy(call_parent);
     }
 }
 
@@ -89,24 +92,59 @@ 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);
 }
 
@@ -149,7 +187,7 @@ bool symbol::info(unsigned inf) const
         inf==info_flags::rational_function) {
         return true;
     } else {
-        return basic::info(inf);
+        return inherited::info(inf);
     }
 }
 
@@ -158,23 +196,23 @@ 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 ? _ex1() : _ex0();
@@ -201,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
 {
     GINAC_ASSERT(ls.nops()==lr.nops());
 #ifdef DO_GINAC_ASSERT
-    for (int i=0; i<ls.nops(); i++) {
+    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 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);
         }
@@ -221,7 +259,20 @@ 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
 {
     GINAC_ASSERT(is_of_type(other,symbol));
     const symbol *o = static_cast<const symbol *>(&other);
@@ -229,7 +280,7 @@ int symbol::compare_same_type(basic const & other) const
     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
 {
     GINAC_ASSERT(is_of_type(other,symbol));
     const symbol *o = static_cast<const symbol *>(&other);
@@ -266,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;
@@ -305,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
@@ -316,6 +367,6 @@ symbol::assigned_ex_info::assigned_ex_info(void) : is_assigned(0), refcount(1)
 {
 }
 
-#ifndef NO_GINAC_NAMESPACE
+#ifndef NO_NAMESPACE_GINAC
 } // namespace GiNaC
-#endif // ndef NO_GINAC_NAMESPACE
+#endif // ndef NO_NAMESPACE_GINAC