Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Call to Clingo::Control::symbolic_atoms() fails after replacing GroundProgramObserver? #19

Closed
iensen opened this issue Dec 19, 2016 · 4 comments
Assignees

Comments

@iensen
Copy link

iensen commented Dec 19, 2016

Hello,

For some reason the following program:


#include <clingo.hh>
#include <iostream>

using namespace Clingo;


class MyObserver: public GroundProgramObserver {
    virtual void output_atom(Clingo::Symbol symbol, atom_t atom) override {
        std:: cout <<"ATOM_ID: "<<  atom << std::endl;
        std:: cout <<"SYMBOL: " << symbol.to_string() << std::endl;
    }
};

int main(int argc, char const **argv) {
    try {
        Logger logger = [](WarningCode, char const *message) {
            std::cerr << message << std::endl;
        };

        MyObserver obs;
        Control ctl{{argv+1, size_t(argc-1)}, logger, 20};
        ctl.register_observer(obs);
        ctl.add("base", {}, " q(a). p(a).");
        ctl.ground({{"base", {}}});
        ctl.solve();
        ctl.symbolic_atoms();
        std:: cout << "OK1" << std::endl;
        GroundProgramObserver dummy_obs2;
        ctl.register_observer(dummy_obs2, true);
        ctl.symbolic_atoms();
        std::cout << "OK2";
    }
    catch (std::exception const &e) {
        std::cerr << "example failed with: " << e.what() << std::endl;
    }
}

crashes when reaching the second occurrence of

ctl.symbolic_atoms();

(So I don't see "OK2" printed)
The exception message is as follows:
domain introspection only supported in clingo mode

Is this an intended behavior?
Is there a way I can look at symbolic atoms after updating the observer?

Thanks!

@iensen iensen changed the title Call to symbolic_atoms() fails after replacing GroundProgramObserver? Call to Clingo::Control::symbolic_atoms() fails after replacing GroundProgramObserver? Dec 19, 2016
@rkaminsk
Copy link
Member

You called the register_observer function with replace=true. Note that this not just replaces the previously registered observer but also the solver backend. Furthermore, clingo is switched into gringo mode not offering some functionality anymore including symbol inspection.

While I could remove the limitation regarding symbolic atoms, replacing the solver backend is probably not what you want anyway. Currently, it is not possible to remove a backend. This would require an additional function. Something like Control::unregister_observer.

@iensen
Copy link
Author

iensen commented Dec 20, 2016

Roland,

Thank you for your time and clear explanations!

You are right, I just need to remove the observer backend!

When multishot solving is used, the observer's functions are being called every time .solve() is called, while I only need to inspect the grounding once. The dependency graph which I build in the computation was, all of a sudden, growing bigger and bigger with more solve() calls :)

I actually expected the observer's callbacks to be triggered when Clingo::Control::ground() method is called, while it seems to be triggered by the solve() calls. Actually, I am still curious what may possibly trigger the observer callbacks.

I was somewhat confused by the error message, so I wanted to make sure the "switch" from clingo mode is intended. Now I see that it's not just a switch...

Anyways, this is not a real issue, I can probably introduce a state in the ground program observer to make sure the graph is not built more than once.

Best,
Evgenii.

@rkaminsk
Copy link
Member

Before a program is passed to the solver, some more rewriting is happening. This is why the observer is also called at the beginning of solving. From the API perspective this is of course ugly. Ideally, the observer should only be called during grounding. In practice, this should work for most observer methods except for end_program() and assume(), which have to be called immediately before solving. I look into this before the next release.

@iensen
Copy link
Author

iensen commented Dec 20, 2016

Roland,

Actually, I just found that the observer is only called at the beginning of solving. For this program:

#include <clingo.hh>
#include <iostream>

using namespace Clingo;


class MyObserver: public GroundProgramObserver {
    virtual void output_atom(Clingo::Symbol symbol, atom_t atom) override {
        std:: cout <<"ATOM_ID: "<<  atom << std::endl;
        std:: cout <<"SYMBOL: " << symbol.to_string() << std::endl;
    }
};

int main(int argc, char const **argv) {
    try {
        Logger logger = [](WarningCode, char const *message) {
            std::cerr << message << std::endl;
        };

        MyObserver obs;
        Control ctl{{argv+1, size_t(argc-1)}, logger, 20};
        ctl.register_observer(obs);
        ctl.add("base", {}, " q(a). p(a).");
        ctl.ground({{"base", {}}});
    }
    catch (std::exception const &e) {
        std::cerr << "example failed with: " << e.what() << std::endl;
    }
}

no observer callbacks are called.

Anyway, I have found some workarounds already, and, while it would be nice to improve the API, I am quite happy with the way things are.

Thanks!

@rkaminsk rkaminsk self-assigned this Jan 26, 2017
rkaminsk added a commit that referenced this issue Jun 4, 2018
@rkaminsk rkaminsk closed this as completed Jun 4, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants