Dear all,


I got a strange behaviour while implementing the archive in user-defined class,

to make the behaviour more explicitly, let me post the C++ code here:


#include <ginac/ginac.h>

#include <fstream>


using namespace GiNaC;

using namespace std;


class Symbol : public symbol {

GINAC_DECLARE_REGISTERED_CLASS(Symbol, symbol)

public:

    Symbol(const string &s);

    void archive(archive_node & n) const override;

    void read_archive(const archive_node& n, lst& sym_lst) override;

    unsigned calchash() const override;

};

GINAC_DECLARE_UNARCHIVER(Symbol);


GINAC_IMPLEMENT_REGISTERED_CLASS(Symbol, symbol)

GINAC_BIND_UNARCHIVER(Symbol);


const symbol & get_symbol(const string & s) {

    static map<string, symbol> dict;

    if (dict.find(s) == dict.end()) dict[s] = symbol(s);

    return dict[s];

}


Symbol::Symbol() { }

Symbol::Symbol(const string &s) : symbol(get_symbol(s)) {  }

int Symbol::compare_same_type(const basic &other) const {

    const Symbol &o = static_cast<const Symbol &>(other);

    int ret = get_name().compare(o.get_name());

    if(ret==0) return 0;

    else if(ret<0) return -1;

    else return 1;

}

 

void Symbol::archive(archive_node & n) const {

    inherited::archive(n);

}

    

void Symbol::read_archive(const archive_node& n, lst& sym_lst) {

    inherited::read_archive(n, sym_lst);

    *this = Symbol(get_name());

}


unsigned Symbol::calchash() const {

    static auto hash = symbol("_").gethash();

    return hash;

}


int main() {

    Symbol k1("k1"), k2("k2");

    auto garfn = "tmp.gar";

    

    {

        archive ar;

        ex val = lst{ k1*k1, k2*k2 };

        ar.archive_ex(val, "key");

        ofstream out(garfn);

        out << ar;

        out.close();

        cout << "writed: " << val << endl;

    } {

        archive ar;

        ifstream in(garfn);

        in >> ar;

        in.close();

        auto val = ar.unarchive_ex(lst{}, "key");

        cout << "read: " << val << endl;

    }

    // console output is

    // writed: {k1^2,k2^2}

    // read: {k1^2,k2^2}

    

    {

        archive ar;

        ex val = lst{ k1*k1==0, k2*k2==0 };

        ar.archive_ex(val, "key");

        ofstream out(garfn);

        out << ar;

        out.close();

        cout << "writed: " << val << endl;

    } {

        archive ar;

        ifstream in(garfn);

        in >> ar;

        in.close();

        auto val = ar.unarchive_ex(lst{}, "key");

        cout << "read: " << val << endl;

    }

    // console output is

    // writed: {k1^2==0,k2^2==0}

    // read: {k1^2==0,k1^2==0} 

    // Note that the last line above, both items are the same: k1^2==0

    

    return 0;

}


Here I want to introduce a class Symbol, when one defines Symbol a(“a”), b(“a”);,

then a and b will be the same or equal, so I override the method compare_same_type.



The last console output seems very strange to me, the both items are the same,

while the expected result is "read: {k1^2==0,k2^2==0}”.


Thanks very much!


Best regards!

Feng