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

Multiple conditions in the head of a condition literal #504

Closed
cabralpinto opened this issue Jun 11, 2024 · 11 comments
Closed

Multiple conditions in the head of a condition literal #504

cabralpinto opened this issue Jun 11, 2024 · 11 comments
Labels

Comments

@cabralpinto
Copy link

cabralpinto commented Jun 11, 2024

I'm struggling to understand why the following code gives me 'F'' is unsafe.

progression(O, F, S, R) :- operation(O, F, S, R); F != F', F != S' : operation(_, F', S', R'), R' > R.

It seems that clingo is interpreting F != F' as if it is outside of the conditional literal. Is it not possible to have multiple conditions in the head of a condition literal? Indeed, the documentation seems to imply that it isn't. But then, why does running the following code not give me the same error?

neq(X, Y) :- X != Y, variable(X), variable(Y).
progression(O, F, S, R) :- operation(O, F, S, R); neq(F, F'), neq(F, S') : operation(_, F', S', R'), R' > R.
@ejgroene
Copy link

ejgroene commented Jun 11, 2024 via email

@ejgroene
Copy link

ejgroene commented Jun 11, 2024 via email

@cabralpinto
Copy link
Author

@ejgroene Thanks for your response! But I still don't understand how to fix the issue. What would you do?

@ejgroene
Copy link

ejgroene commented Jun 11, 2024 via email

@rkaminsk
Copy link
Member

We cannot help you here without knowing what the program is supposed to mean. If you are beginning to write ASP, I would suggest to completely ignore conditional literals and write your program without.

@rkaminsk
Copy link
Member

To get started, you could check out our guide or the book Answer Set Programming by Vladimir Lifschitz. There is also a free draft available.

@cabralpinto
Copy link
Author

Hey @rkaminsk, I am quite new but I've already read much of the guide and I'm still unable to fix the issue without resorting to a verbose solution.

My objective with the excerpt I sent is as follows. Given a set of arithmetic operations, such as the one below, I want to create a corresponding progression predicate for every operation that has none of its operands used again in the operations that follow (tested with R' > R).

operation("-", "A", "B", "C"). % A - B = C
operation("+", "C", "D", "E"). % C + D = E
operation("+", "C", "F", "G"). % C + F = G

In this example, I'd want my code to output progression("-", "A", "B", "C"). and progression("+", "C", "F", "G"). The second operation doesn't get a progression predicate because C is used again in the following operation. The full code I wrote for this is as follows (before I had shown you a simplified version only to showcase the error):

progression(O, F, S, R) :-
  operation(O, F, S, R);
  F != F', F != S', S != F', S != S' : operation(_, F', S', R'), R' > R.

I can fix the error by splitting the conditions into multiple condition literals (seen below), but this results in a lot of code repetition. Isn't there a cleaner option?

progression(O, F, S, R) :- 
  operation(O, F, S, R);
  F != F' : operation(_, F', S', R'), R' > R;
  F != S' : operation(_, F', S', R'), R' > R;
  S != F' : operation(_, F', S', R'), R' > R;
  S != S' : operation(_, F', S', R'), R' > R.

@rkaminsk
Copy link
Member

rkaminsk commented Jun 11, 2024

What about the following?

operation("-", "A", "B", "C"). % A - B = C
operation("+", "C", "D", "E"). % C + D = E
operation("+", "C", "F", "G"). % C + F = G

arg(X,R) :- operation(_,X,_,R).
arg(X,R) :- operation(_,_,X,R).

progression(O, F, S, R) :- operation(O, F, S, R); 
    #count { R' : arg(F;R';S;R'), R' > R } == 0

@cabralpinto
Copy link
Author

Good idea! Thank you.

However, as a noobie, I can't help but wonder why clingo was designed without some of the constructs that are commonplace in most languages, like parenthesis to take precedence or the "or" operator. I feel like I spend most of my time finding ways to go around these missing features. Could you provide some insight on why it is the way it is? Is there maybe any plan to add these things in the future?

@rkaminsk
Copy link
Member

However, as a noobie, I can't help but wonder why clingo was designed without some of the constructs that are commonplace in most languages, like parenthesis to take precedence or the "or" operator. I feel like I spend most of my time finding ways to go around these missing features. Could you provide some insight on why it is the way it is? Is there maybe any plan to add these things in the future?

In my experience, one does not need nested Boolean connectives for modeling most tasks. It is possible to encode a lot of problems mainly using normal rules. One design goal of the language has always been to keep the language as simple as possible but expressive (in sense of being able to write compact encodings). It is normal that it takes some time to develop a feeling for encoding problems. It might take a little longer to come up with good ASP code but in the end you get something compact and maybe even nicely readable.

You can even encode your problem just with normal rules:

arg(X,R) :- operation(_,X,_,R).
arg(X,R) :- operation(_,_,X,R).

covered(R) :- arg(X,R), arg(X,R'), R'>R.

progression(O,F,S,R) :- operation(O,F,S,R), not covered(R).

@cabralpinto
Copy link
Author

cabralpinto commented Jun 12, 2024

I ended up managing to code it with just one rule! I just adapted your first idea a little:

#count { R' : operation(_, F', S', R'), (F; S) = (F'; S'), R' > R } = 0.

Thanks for your input. What I would argue is that adding parenthesis (to define precedence) and the or operator would result in more expressive code without adding any significant complexity or readability issues for the end user. I hope you consider it!

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

No branches or pull requests

3 participants