|
GiNaC
1.6.2
|
00001 00005 /* 00006 * GiNaC Copyright (C) 1999-2011 Johannes Gutenberg University Mainz, Germany 00007 * 00008 * This program is free software; you can redistribute it and/or modify 00009 * it under the terms of the GNU General Public License as published by 00010 * the Free Software Foundation; either version 2 of the License, or 00011 * (at your option) any later version. 00012 * 00013 * This program is distributed in the hope that it will be useful, 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00016 * GNU General Public License for more details. 00017 * 00018 * You should have received a copy of the GNU General Public License 00019 * along with this program; if not, write to the Free Software 00020 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00021 */ 00022 00023 #include "wildcard.h" 00024 #include "archive.h" 00025 #include "utils.h" 00026 #include "hash_seed.h" 00027 00028 #include <iostream> 00029 00030 namespace GiNaC { 00031 00032 GINAC_IMPLEMENT_REGISTERED_CLASS_OPT(wildcard, basic, 00033 print_func<print_context>(&wildcard::do_print). 00034 print_func<print_tree>(&wildcard::do_print_tree). 00035 print_func<print_python_repr>(&wildcard::do_print_python_repr)) 00036 00037 00038 // default constructor 00040 00041 wildcard::wildcard() : label(0) 00042 { 00043 setflag(status_flags::evaluated | status_flags::expanded); 00044 } 00045 00047 // other constructors 00049 00050 wildcard::wildcard(unsigned l) : label(l) 00051 { 00052 setflag(status_flags::evaluated | status_flags::expanded); 00053 } 00054 00056 // archiving 00058 00059 void wildcard::read_archive(const archive_node& n, lst& sym_lst) 00060 { 00061 inherited::read_archive(n, sym_lst); 00062 n.find_unsigned("label", label); 00063 setflag(status_flags::evaluated | status_flags::expanded); 00064 } 00065 GINAC_BIND_UNARCHIVER(wildcard); 00066 00067 void wildcard::archive(archive_node &n) const 00068 { 00069 inherited::archive(n); 00070 n.add_unsigned("label", label); 00071 } 00072 00074 // functions overriding virtual functions from base classes 00076 00077 int wildcard::compare_same_type(const basic & other) const 00078 { 00079 GINAC_ASSERT(is_a<wildcard>(other)); 00080 const wildcard &o = static_cast<const wildcard &>(other); 00081 00082 if (label == o.label) 00083 return 0; 00084 else 00085 return label < o.label ? -1 : 1; 00086 } 00087 00088 void wildcard::do_print(const print_context & c, unsigned level) const 00089 { 00090 c.s << "$" << label; 00091 } 00092 00093 void wildcard::do_print_tree(const print_tree & c, unsigned level) const 00094 { 00095 c.s << std::string(level, ' ') << class_name() << "(" << label << ")" << " @" << this 00096 << std::hex << ", hash=0x" << hashvalue << ", flags=0x" << flags << std::dec 00097 << std::endl; 00098 } 00099 00100 void wildcard::do_print_python_repr(const print_python_repr & c, unsigned level) const 00101 { 00102 c.s << class_name() << '(' << label << ')'; 00103 } 00104 00105 unsigned wildcard::calchash() const 00106 { 00107 // this is where the schoolbook method 00108 // (golden_ratio_hash(typeid(*this).name()) ^ label) 00109 // is not good enough yet... 00110 unsigned seed = make_hash_seed(typeid(*this)); 00111 hashvalue = golden_ratio_hash(seed ^ label); 00112 setflag(status_flags::hash_calculated); 00113 return hashvalue; 00114 } 00115 00116 bool wildcard::match(const ex & pattern, exmap& repl_lst) const 00117 { 00118 // Wildcards must match each other exactly (this is required for 00119 // subs() to work properly because in the final step it substitutes 00120 // all wildcards by their matching expressions) 00121 return is_equal(ex_to<basic>(pattern)); 00122 } 00123 00124 bool haswild(const ex & x) 00125 { 00126 if (is_a<wildcard>(x)) 00127 return true; 00128 for (size_t i=0; i<x.nops(); ++i) 00129 if (haswild(x.op(i))) 00130 return true; 00131 return false; 00132 } 00133 00134 } // namespace GiNaC