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

Cut, If-Then in CLP(Z) #2708

Open
notoria opened this issue Dec 14, 2024 · 4 comments
Open

Cut, If-Then in CLP(Z) #2708

notoria opened this issue Dec 14, 2024 · 4 comments

Comments

@notoria
Copy link
Contributor

notoria commented Dec 14, 2024

The construct (->)/2 is used in fold_statement/3:

( List = [] -> Statement = 1

The construct !/0 is used intervals_to_domain/2:

intervals_to_domain([], empty) :- !.

Is it safe to remove rewrite it?

@notoria
Copy link
Contributor Author

notoria commented Dec 14, 2024

Could the monotonic mode remove this:

reify_(E, B) --> { var(E), !, E = B }.

Something similar to this:

{ var(E), !, \+ monotonic }.

@notoria
Copy link
Contributor Author

notoria commented Dec 14, 2024

Is !/0 missing here:

reifiable(E) :- var(E), non_monotonic(E).

Should the unification in the head be delayed:

single_value(V, V) :- var(V), !, non_monotonic(V).

@triska
Copy link
Contributor

triska commented Dec 15, 2024

Thank you a lot for looking at this! It would definitely be nice to use better constructs in the implementation.

Regarding these concrete cases: Even though (->)/2 or !/0 play a role in all these cases, the situations are all quite distinct:

  • l. 3832: this was added before Scryer benefited from first instantiated argument indexing which you generously contributed nearly 4 years ago in 657e4f1, and it can therefore now be written efficiently without using impure constructs
  • l. 1715: removing !/0 would leave an unintended alternative
  • l. 3728: yes
  • l. 3707: no, due to the calling context in which the predicate is always used
  • l. 2316: it need not, for the same reason as above.

@notoria
Copy link
Contributor Author

notoria commented Dec 15, 2024

Thank you a lot for looking at this! It would definitely be nice to use better constructs in the implementation.

It's no trouble.

For intervals_to_domain/2, this could be done:

intervals_to_domain([], empty).
intervals_to_domain([I|Is], D) :-
    intervals_to_domain_(I, Is, D).

intervals_to_domain_(I0, [], from_to(M,N)) :-
    I0 = M-N.
intervals_to_domain_(I0, [I1|Is0], D) :-
        Is = [I0|[I1|Is0]],
        length(Is, L),
        FL is L // 2,
        length(Front, FL),
        append(Front, Tail, Is),
        Tail = [n(Start)-_|_],
        Hole is Start - 1,
        intervals_to_domain(Front, Left),
        intervals_to_domain(Tail, Right),
        D = split(Hole, Left, Right). % can be moved to the head.

But depending on the context there might be some choice points.

I was hoping to change reify_(E, B) --> { var(E), !, E = B }. into reify_(E, B) --> { var(E), !, non_monotonic(E), E = B }. but reify_(E, B) --> { var(E), !, \+ monotonic, E = B }. could work too.

Could the monotonic mode be used here:

cis_goals(V, V) --> { var(V) }, !.

Is it possible for the second factor to be the integer and not the first:
linsum(A*N, S0, S) --> { integer(N) }, !, mulsum(A, N, S0, S).

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

2 participants