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

Feature Request: Persistent constraint store in top-level #3

Closed
fnogatz opened this issue Sep 17, 2016 · 7 comments
Closed

Feature Request: Persistent constraint store in top-level #3

fnogatz opened this issue Sep 17, 2016 · 7 comments

Comments

@fnogatz
Copy link

fnogatz commented Sep 17, 2016

As already discussed in pull request #2 it is a common request to have a persistent constraint store in SWI's top-level. My suggestion was to have a new chr_option(persistent_store, OffOn). Unfortunately it is not enough to simply prevent the top-level's backtracking by changing the used b_setval into nb_setval for saving constraints.

@JanWielemaker already proposed some thoughts on this in #2:

If we want an incremental toplevel for CHR it might be better to see whether the normal Prolog toplevel could be changed from backtracking to a recursive loop. That is surely possible. Also there I'm not sure it is the right direction. I tend to prefer the SWISH toplevel which gives you a completely fresh environment for each query.

I am willing in implementing an alternative approach again, but I am not sure if the requested behaviour is ok for Jan and which would be the best starting point for implementation. Let's use this issue to track this down :)

@JanWielemaker
Copy link
Member

As stated, I don't think that CHR is the place to change this. It would need to go into boot/toplevel.pl,
'$query_loop'/0. Some flag could choose between the traditional backtracking and a recursive toplevel loop. Mostly this should be rather trivial.

There is one issue: if the user makes some error the exception will still tear down the CHR store. This can be avoided using a catch/3, but as the comment above already states, this means the exception will not be considered `uncaught' and the toplevel won't do its normal magic with uncaught exceptions. It is not entirely sure how to remedy that. Possibly with a foreign routine for calling the actual goal.

There is probably also some magic needed to switch between the two styles.

The alternative is to implement e.g. chr/0 that will run the alternative toplevel. Not sure what is best. Guess it depends on whether or not this makes any sense outside the context of CHR. In theory you can have other stuff depending on global variables, but I'm not aware of a concrete similar example.

@fnogatz
Copy link
Author

fnogatz commented Sep 17, 2016

In theory you can have other stuff depending on global variables, but I'm not aware of a concrete similar example.

The same use-case might apply for clpfd, where one could add constraints step by step:

?- use_module(library(clpfd)).
?- X in 0..10.
X in 0..10.
?- X in 10..20.
X = 10.

Maybe @triska can tell if this a desired behaviour for clpfd, too.

@triska
Copy link
Member

triska commented Sep 18, 2016

@fnogatz: Please post this question, suitably generalized, to stackoverflow.com, using the prolog tag. This is a feature that should definitely be added, in such a way that it:

  1. works in SICStus Prolog too
  2. works for other constraint solvers as well.

There are several ways to do this, and it would be great to see the feedback from other Prolog vendors too.

@JanWielemaker
Copy link
Member

As the toplevel is a pretty complex beast, I've done a little hacking myself. Using the latest GIT version you can do

?- set_prolog_flag(toplevel_mode, recursive).

and backtrackable global variables are maintained. This also causes toplevel bindings to be maintained on the stacks without copying them, so $Var refers to a not copied previous answer. Experience will show
how well this works.

@fnogatz
Copy link
Author

fnogatz commented Sep 19, 2016

Jan, thanks for adding this. I installed latest GIT version and for CHR it is now working as I had in mind. However, it does not seem like a general solution, as clpfd contstraints are not kept, probably because they don't use global variables.

?- use_module(library(clpfd)).
true.

?- set_prolog_flag(toplevel_mode, recursive).
true.

?- X = 0..10.
X = 0..10.

?- X = 10..20.
X = 10..20.    % would expect X = 10.

@JanWielemaker
Copy link
Member

It works, but differently. First of all X = 0..10 just creates a term, so I guess you mean X in 0..10.
Second, you expect variables of a previous answer to unify with the next query. That is of course technically possible, but I really wonder whether that makes any sense. It will surely make a rather weird toplevel, doing things like this:

?- A = 1.
A = 1.
?- A = 2.
false.

I doubt that is what we want. You can refer to old answer variables using $Var, as you could always do in SWI-Prolog, except that before $Var would refer to a copy while now it refers to the real answer. So,
we get this:

6 ?- X in 0..10.
X in 0..10.

7 ?- $X in 10..20.
true.

8 ?- writeln($X).
10
true.

Now it only might make sense to make it write

?- X in 0..10.
X in 0..10.

?- $X in 10..20.
X = 10.

That might be feasible.

@fnogatz
Copy link
Author

fnogatz commented Sep 19, 2016

Thank you for the clarification. The shorter notation you suggested at the end, i.e. returning X = 10 instead of true would be nice. But I am already very, very happy with the rest :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants